Skip to content

Endpoint reference ​

Every route Ambikly registers, grouped by resource. Read REST API first for authentication, the response envelope and pagination.

Routes are relative to a namespace base URL:

  • ambikly/v1 → https://example.com/wp-json/ambikly/v1
  • ambikly-pro/v1 → https://example.com/wp-json/ambikly-pro/v1

The free core registers 117 route calls (123 at runtime); Pro registers 94 (99 at runtime).

Reading the permission column ​

LabelPermission callbackPasses for
Managestore_permission()ambikly_manage_store or manage_options — Administrator, Store Manager
Viewstore_view_permission()ambikly_view_store or the above — adds Support Agent
Adminadmin_permission() / check_permissions()manage_options only
Logged incustomer_permission() or is_user_logged_in()Any authenticated user, no capability required
Publicpublic_permission() / __return_trueAnyone, including logged out

Every Public route is also listed together in Publicly accessible routes.


Free core routes — ambikly/v1 ​

Everything from here to the Pro section is registered by the free core.

Products ​

MethodRoutePermissionNotes
GET/productsViewPaginated. search, category_id, type, status, orderby, order, page, per_page (default 50)
POST/productsManageRejects a sale price that is not lower than the regular price
GET/products/{id}ViewFull product with attributes, variations and files
PUT/products/{id}ManagePartial update
DELETE/products/{id}Manage
GET/products/{id}/usageManageWhere the product is referenced before you delete it
POST/products/bulk-deleteManageBody: { "ids": [1,2,3] }
POST/products/bulk-statusManageBody: { "ids": [...], "status": "published" }
GET/products/{id}/meta/{key}ManageKey matches [a-z0-9_-]+
POST/products/{id}/meta/{key}ManageSet one meta value
DELETE/products/{id}/meta/{key}Manage

Product attributes ​

MethodRoutePermissionNotes
GET/products/{product_id}/attributesView
POST/products/{product_id}/attributesManage
GET/products/{product_id}/attributes/{id}View
PUT/products/{product_id}/attributes/{id}Manage
DELETE/products/{product_id}/attributes/{id}Manage
GET/products/{product_id}/attributes/{attribute_id}/valuesView
POST/products/{product_id}/attributes/{attribute_id}/valuesManage
PUT/products/{product_id}/attributes/{attribute_id}/values/{id}Manage
DELETE/products/{product_id}/attributes/{attribute_id}/values/{id}Manage

Product variations ​

MethodRoutePermissionNotes
GET/products/{product_id}/variationsView
POST/products/{product_id}/variationsManageVariation SKUs carry a UNIQUE key
GET/products/{product_id}/variations/{id}View
PUT/products/{product_id}/variations/{id}Manage
DELETE/products/{product_id}/variations/{id}Manage
POST/products/{product_id}/variations/generateManageBuilds the cartesian product of the attribute values
POST/products/{product_id}/variations/bulk-updateManage
POST/products/{product_id}/variations/bulk-deleteManage

Categories ​

MethodRoutePermissionNotes
GET/categoriesViewPaginated, default per_page 100, default order sort_order ASC
POST/categoriesManage
GET/categories/{id}View
PUT/categories/{id}Manage
DELETE/categories/{id}Manage
POST/categories/bulk-deleteManage
POST/categories/bulk-statusManage

Tags and brands ​

Both taxonomies are registered from the same loop, so the route shapes are identical.

MethodRoutePermissionNotes
GET/tagsPublicStorefront reads this for filtering
POST/tagsManage
PUT/tags/{id}Manage
DELETE/tags/{id}Manage
GET/brandsPublic
POST/brandsManageAccepts name, slug, description, logo, website
PUT/brands/{id}Manage
DELETE/brands/{id}Manage
GET/products/{id}/termsPublicTags and brands attached to a product
POST/products/{id}/termsManageReplaces the product's term assignments

Orders ​

MethodRoutePermissionNotes
GET/ordersViewPaginated, default 25. search, status, payment_status, customer_id, date_from, date_to, orderby, order
POST/ordersManageCreate an order from the admin
GET/orders/statusesViewThe store's order and payment status vocabulary
GET/orders/{id}ViewOrder with items, addresses and transactions
PUT/orders/{id}Manage
DELETE/orders/{id}Manage
POST/orders/{id}/statusManageFires ambikly_order_status_changed
GET/orders/{id}/notesView
POST/orders/{id}/notesManageBody accepts is_customer_visible
POST/orders/{id}/refundManageFires ambikly_order_refunded
POST/orders/{id}/record-paymentManageRecords an off-platform net-terms payment. Not a refund — it releases company credit without marking the order refunded

Invoices and packing slips ​

MethodRoutePermissionNotes
GET/orders/{id}/invoicePublicOwner, staff or ?token= check runs inside the handler and returns an HTML 403 page. ?format=pdf falls back to HTML unless a PDF renderer filter is installed
GET/orders/{id}/packing-slipPublicSame ownership check. Returns 404 when packing slips are disabled for the store

Both return raw HTML and call exit(), so they are not wrapped in the JSON envelope.

Customers ​

MethodRoutePermissionNotes
GET/customersViewPaginated, default 25
POST/customersManage
GET/customers/{id}View
PUT/customers/{id}Manage
DELETE/customers/{id}ManageFires ambikly_customer_deleted
GET/customers/{id}/ordersViewPaginated, default and maximum per_page 100
GET/customers/{id}/addressesView
POST/customers/{id}/addressesManage
PUT/customers/{id}/addresses/{address_id}Manage
DELETE/customers/{id}/addresses/{address_id}Manage

B2B companies ​

These routes back the Ambikly → Companies admin screen, and the /companies/me* set backs company self-service on the storefront. See B2B companies & Net Terms.

MethodRoutePermissionNotes
GET/companiesViewPaginated, default 25
POST/companiesManage
GET/companies/{id}View
PUT/companies/{id}ManageCredit limit, payment terms, price_tier_discount
DELETE/companies/{id}Manage
GET/companies/{id}/ordersView
GET/companies/{id}/buyersView
POST/companies/{id}/buyersManageInvites a buyer login
DELETE/companies/{id}/buyers/{buyer_id}Manage
GET/companies/meLogged inSelf-service: the company the current user owns
GET/companies/me/buyersLogged in
POST/companies/me/buyersLogged inA company owner invites their own buyer
DELETE/companies/me/buyers/{buyer_id}Logged in

Cart ​

Every cart route is public — a guest shopper has no WordPress account. The cart is resolved from the session, not from a parameter.

MethodRoutePermissionNotes
GET/cartPublicItems, coupons and totals
POST/cart/itemsPublicBody: product_id, quantity, optional variation_id
PUT/cart/items/{line_key}Publicline_key is a 32-character hex line identifier
DELETE/cart/items/{line_key}Public
POST/cart/clearPublic
POST/cart/couponsPublicBody: { "code": "SAVE10" }
DELETE/cart/coupons/{code}Public
POST/cart/shippingPublicSets the shipping address and chosen method
POST/cart/billingPublicSets the billing address

Checkout ​

MethodRoutePermissionNotes
POST/checkoutPublicPlaces the order. Fires ambikly_order_created, then ambikly_checkout_completed
GET/checkout/optionsPublicAvailable gateways for this cart and caller, filtered through isAvailable($context)
POST/checkout/shippingPublicShipping rates for an address

Coupons ​

MethodRoutePermissionNotes
GET/couponsViewPaginated, default 25
POST/couponsManage
GET/coupons/{id}View
PUT/coupons/{id}Manage
DELETE/coupons/{id}Manage

Reviews ​

MethodRoutePermissionNotes
GET/reviewsViewAdmin moderation list. Paginated, default 25, maximum 100. status, product_id, search
POST/reviewsPublicShopper submission. Auto-approval decided by ambikly_review_auto_approve; fires ambikly_review_submitted
PUT/reviews/{id}ManageApprove, unapprove or edit
DELETE/reviews/{id}Manage
POST/reviews/bulkManageBody: { "ids": [...], "action": "approve" }
GET/products/{id}/reviewsPublicApproved reviews for one product
GET/products/{id}/reviews/summaryPublicAverage rating and per-star counts

Shipping ​

MethodRoutePermissionNotes
GET/shipping/zonesManageReturns every zone, unpaginated
POST/shipping/zonesManage
PUT/shipping/zones/{id}Manage
DELETE/shipping/zones/{id}Manage
GET/shipping/zones/{id}/methodsManage
POST/shipping/zones/{id}/methodsManage
PUT/shipping/methods/{id}ManageEditable fields are title, cost, tax_status, enabled
DELETE/shipping/methods/{id}Manage

Tax ​

MethodRoutePermissionNotes
GET/tax/ratesManageEvery rate, unpaginated
POST/tax/ratesManage
PUT/tax/rates/{id}Manage
DELETE/tax/rates/{id}Manage

The city column exists in the data model but has no admin column. Matching on country, state and postcode is plain equality plus the * wildcard — ranges and comma lists are not implemented.

Payments ​

MethodRoutePermissionNotes
GET/payments/gatewaysAdminAll registered gateways with their settings
POST/payments/gateways/{id}Admin{id} matches [a-z0-9_-]+. Credentials are stored under a credentials sub-array

Gateway callbacks ​

These are called by the payment provider, not by you. All three are public by necessity and verify the caller inside the handler.

MethodRoutePermissionNotes
POST/stripe/webhookPublicVerifies the Stripe signature header inside the handler
GET/paypal/returnPublicBuyer redirect target after approving a PayPal payment
POST/paypal/webhookPublicPayPal IPN-style notifications

Downloads ​

MethodRoutePermissionNotes
GET/downloads/{token}Public{token} is 32–64 hex characters and is the access control. Applies ambikly_download_file_url, then fires ambikly_download_served
GET/orders/{id}/downloadsViewDownloads granted by one order
GET/customers/{id}/downloadsView
GET/account/downloadsLogged inThe current user's own downloads; also re-checks get_current_user_id() internally

Reports ​

MethodRoutePermissionNotes
GET/reports/summaryViewHeadline totals
GET/reports/sales-by-dayViewTime series
GET/reports/top-productsView
GET/reports/status-breakdownViewOrder counts per status

Jobs ​

Operator visibility into the durable job queue.

MethodRoutePermissionNotes
GET/jobs/statusView{ pending, running, failed } counts
GET/jobs/failedViewMost recent 200 exhausted jobs, newest first
POST/jobs/{id}/retryManageResets attempts to 0 and requeues. Only works on a failed job

Settings ​

MethodRoutePermissionNotes
GET/settingsAdminEvery settings group
POST/settingsAdmin
GET/settings/{group}Admin{group} matches [a-zA-Z0-9_-]+
POST/settings/{group}Admin

Setup wizard ​

Five routes registered from one loop, one per wizard step.

MethodRoutePermissionNotes
POST/setup/storeAdminStore name, address, currency
POST/setup/paymentsAdminEnables offline gateways: cod, bank_transfer, cheque, manual
POST/setup/shippingAdmin
POST/setup/taxAdmin
POST/setup/pagesAdminCreates the store pages

The wizard cannot be relaunched from the admin UI — these routes are the only way to re-run a step.

Email templates ​

MethodRoutePermissionNotes
GET/email-templatesAdminThe four editable templates
POST/email-templatesAdminSaves subject and content per event and audience
POST/email-templates/testAdminSends a test message

Import and export ​

MethodRoutePermissionNotes
GET/export/productsAdminStreams CSV. status, type, ids (comma-separated)
GET/export/ordersAdminStreams CSV. status, from, to
POST/import/productsAdminCSV upload
GET/import/products/templateAdminBlank CSV with the expected header row

Webhooks ​

MethodRoutePermissionNotes
GET/webhooksAdminSecrets are masked except the last four characters
POST/webhooksAdminReturns the real secret once. Requires an http/https URL
GET/webhooks/eventsAdminThe nine-event catalog, flat and grouped by prefix
GET/webhooks/{id}Admin
PUT/webhooks/{id}AdminA secret in the body is discarded — secrets cannot be rotated in place
DELETE/webhooks/{id}AdminAlso deletes that webhook's delivery log
POST/webhooks/{id}/activateAdmin
POST/webhooks/{id}/deactivateAdmin
POST/webhooks/{id}/testAdminSends synchronously and reports the real outcome. Body: optional event
GET/webhooks/{id}/deliveriesAdminMost recent 200 attempts

System ​

MethodRoutePermissionNotes
GET/system/statusAdminEnvironment, versions and table checks

Ambikly Pro routes — ambikly-pro/v1 ​

Pro routes register only when Ambikly Pro is active. Add-on routes register only when that add-on is enabled and the license is currently valid — an expired license stops every add-on's routes from registering, while leaving its settings intact.

Add-ons ​

MethodRoutePermissionNotes
GET/addonsViewAll 35 add-ons with metadata, settings and settings schema. Secrets are masked
GET/addons/{slug}View
POST/addons/{slug}/enableManageReturns license_required (403) without a valid license
POST/addons/{slug}/disableManage
POST/addons/{slug}/settingsManageResponse carries an adjusted key naming any value that was clamped

License ​

MethodRoutePermissionNotes
GET/licenseAdminStored key and cached status
POST/licenseAdminSave the key
POST/license/activateAdminCalls the EDD licensing API
POST/license/deactivateAdminClears cached details; the stored key stays in place
POST/license/checkAdminRevalidates now instead of waiting for the daily check

Add-on routes ​

Abandoned Cart — /addons/abandoned-cart ​

MethodRoutePermissionNotes
GET/admin/abandoned-cartsView

Advanced Reports — /addons/advanced-reports ​

MethodRoutePermissionNotes
GET/reports/cohortView
GET/reports/rfmView
GET/reports/top-customersView
GET/reports/exportView

Advanced Shipping — /addons/advanced-shipping ​

MethodRoutePermissionNotes
GET, POST, DELETE/shipping-rulesManageOne registration serving all three methods

Advanced Variations — /addons/advanced-variations ​

MethodRoutePermissionNotes
GET/variation-swatchesPublicThe storefront renders swatches from this
POST/variation-swatchesManage

Affiliate — /addons/affiliate ​

MethodRoutePermissionNotes
GET/affiliate/dashboardLogged inThe caller's own affiliate stats
POST/affiliate/registerLogged in
POST/affiliate/mark-paidManage
POST/affiliate/{id}ManageUpdate one affiliate

AI Descriptions — /addons/ai-descriptions ​

MethodRoutePermissionNotes
POST/ai/describeManage

AI Recommendations — /addons/ai-recommendations ​

MethodRoutePermissionNotes
GET/recommendationsPublicStorefront recommendation strip
POST/recommendations/rebuildManageRebuilds the similarity index

AJAX Filters — /addons/ajax-filters ​

MethodRoutePermissionNotes
GET/filtered-productsPublicBacks the storefront filter widget

Bundles — /addons/bundles ​

MethodRoutePermissionNotes
GET/products/{id}/bundle-itemsView
PUT/products/{id}/bundle-itemsManageReplaces the bundle contents
POST/products/{id}/bundle-itemsManageSame handler as PUT
DELETE/products/{id}/bundle-itemsManage

Checkout Field Editor — /addons/checkout-field-editor ​

MethodRoutePermissionNotes
GET/checkout-fieldsView
POST/checkout-fieldsManageStores a field schema. The core checkout does not yet consume it

Compare — /addons/compare ​

MethodRoutePermissionNotes
GET/comparePublicSide-by-side product data

CRM Sync — /addons/crm-sync ​

MethodRoutePermissionNotes
GET/crm-sync/statusViewSync log summary

Download Analytics — /addons/download-analytics ​

MethodRoutePermissionNotes
GET/download-analyticsView

Dynamic Pricing — /addons/dynamic-pricing ​

MethodRoutePermissionNotes
GET/pricing-rulesView
POST/pricing-rulesManage
GET/pricing-rules/metaViewCondition and discount-type vocabulary for the rule builder
GET/pricing-rules/{id}View
PUT/pricing-rules/{id}Manage
DELETE/pricing-rules/{id}Manage
POST/pricing-rules/{id}/activateManage
POST/pricing-rules/{id}/deactivateManage

Flash Sales — /addons/flash-sales ​

MethodRoutePermissionNotes
GET/flash-salesManage
POST/flash-salesManage
DELETE/flash-salesManage

Gift Cards — /addons/gift-cards ​

MethodRoutePermissionNotes
POST/cart/gift-cardsPublicRedeem a code against the current cart
DELETE/cart/gift-cards/{code}Public{code} matches [A-Z0-9-]+
POST/gift-cards/lookupPublicBalance check by code. See the note below
GET/gift-cardsView
POST/gift-cardsManageIssue a card
GET/gift-cards/{id}View
POST/gift-cards/{id}/adjustManageCredit or debit a balance
POST/gift-cards/{id}/cancelManage
POST/gift-cards/bulkManageIssue in bulk

License Pro — /addons/license-pro ​

This add-on turns your own store into a license server, so its activation routes are necessarily public — they are called by software running on your customers' sites.

MethodRoutePermissionNotes
POST/licenses/activatePublicCalled by a customer's installation
POST/licenses/deactivatePublic
POST/licenses/checkPublic
GET/updates/{slug}PublicUpdate manifest for a licensed product
GET/admin/licensesView
GET/admin/licenses/{id}View
POST/admin/licenses/{id}/revokeManage
POST/admin/licenses/{id}/reinstateManage
POST/admin/licenses/{id}/clear-activationsManage
POST/admin/licenses/bulkManage

Loyalty Points — /addons/loyalty-points ​

MethodRoutePermissionNotes
POST/cart/loyaltyLogged inRedeem points against the cart
DELETE/cart/loyaltyLogged in
GET/loyalty/balanceLogged in
GET/loyalty/historyLogged in
POST/loyalty/adjustManageStaff credit or debit

Multi-Vendor — /addons/multi-vendor ​

MethodRoutePermissionNotes
GET/vendors/meLogged in
POST/vendors/signupLogged in
GET/vendorsView
POST/vendors/{id}Logged inPermitted for any logged-in user at the route level; which fields a non-staff caller may change is narrowed inside the handler
POST/vendors/{id}/approveManage
POST/vendors/{id}/rejectManage
POST/vendors/{id}/suspendManage
POST/vendors/{id}/mark-paidManage
POST/products/{id}/vendorManageAssigning a product to a vendor is a store decision

Order Bumps — /addons/order-bumps ​

MethodRoutePermissionNotes
GET/order-bumpsView
POST/order-bumpsManage
GET/order-bumps/{id}View
PUT/order-bumps/{id}Manage
DELETE/order-bumps/{id}Manage
GET/checkout/order-bumpsPublicBumps eligible for the current cart
POST/checkout/order-bumps/{id}/acceptPublic
DELETE/checkout/order-bumps/{id}/declinePublic
MethodRoutePermissionNotes
POST/popup-leadsPublicLead capture from the storefront popup

Post-Purchase Upsells — /addons/post-purchase-upsells ​

MethodRoutePermissionNotes
POST/upsell/acceptPublicCharges the stored payment method via chargeAdditional()
POST/upsell/declinePublic

Product Badges — /addons/product-badges ​

MethodRoutePermissionNotes
GET/badgesPublic

Quick View — /addons/quick-view ​

MethodRoutePermissionNotes
GET/quick-view/{id}PublicProduct summary for the modal

Shipment Tracking — /addons/shipment-tracking ​

MethodRoutePermissionNotes
GET/shipmentsLogged in⚠️ See the warning below
POST/shipmentsManageRefuses an order_id that does not exist, and de-duplicates carrier plus tracking number
DELETE/shipments/{id}ManageReverts the order to unshipped only when no shipments remain

GET /ambikly-pro/v1/shipments is open to any logged-in user

Its permission callback is current_user_can('ambikly_view_store') || current_user_can('manage_options') || is_user_logged_in() — the final clause makes the first two redundant, so the route admits every authenticated user including Subscribers. Row-level filtering does happen inside the handler: a caller without ambikly_view_store is resolved to their own ambikly_customers.id and can only see shipments for their own orders. The gate is therefore in the callback body rather than the permission callback. If you audit permission callbacks statically, this route will look more open than it behaves.

Size Chart — /addons/size-chart ​

MethodRoutePermissionNotes
GET/size-chartPublic
MethodRoutePermissionNotes
GET/smart-searchPublicTypeahead search results

Store Credit — /addons/store-credit ​

MethodRoutePermissionNotes
POST/cart/store-creditLogged inApply credit to the cart
DELETE/cart/store-creditLogged in
GET/store-creditLogged inThe caller's own balance
POST/store-credit/adjustManageStaff credit or debit

Subscriptions — /addons/subscriptions ​

MethodRoutePermissionNotes
GET/subscriptionsViewStaff list
GET/subscriptions/{id}View or ownerA customer may read their own subscription
POST/subscriptions/{id}/cancelManage or ownerA read-only Support Agent cannot act on a customer's behalf
POST/subscriptions/{id}/pauseManage or owner
POST/subscriptions/{id}/resumeManage or owner
POST/subscriptions/{id}/chargeManageStaff only — never the owner

Ownership is matched on ambikly_subscriptions.user_id against get_current_user_id(), and a logged-out caller (user id 0) never matches.

Wishlist — /addons/wishlist ​

MethodRoutePermissionNotes
GET/wishlistPublicGuest wishlists are resolved by session key
POST/wishlist/itemsPublic
DELETE/wishlist/items/{id}Public

Add-ons with no REST routes ​

Five add-ons register no routes of their own. They hook the storefront, the admin or the job queue instead, and where they need an API they reuse the core /cart and /checkout endpoints.

Add-onHow it works instead
One-Page CheckoutRe-renders the core cart and checkout on one page, calling /cart and /checkout
PDF StampingFilters the download file URL and stamps on delivery
Recently ViewedBrowser-side history plus a storefront shortcode
Social LoginOAuth redirects, not REST
Sticky Add to CartFront-end only; posts to /cart/items

Publicly accessible routes ​

Every route below has a permission callback of public_permission() or __return_true, meaning no authentication and no capability check happens before the handler runs. Most of them are public by design — a guest shopper has no account — and several perform their own access control inside the handler. Review this list when you audit the site, and note it when you put a WAF or an API gateway in front of WordPress.

ambikly/v1 ​

MethodRouteWhy it is publicAccess control inside the handler
GET/cartGuest shoppingSession-scoped
POST/cart/itemsGuest shoppingSession-scoped
PUT/cart/items/{line_key}Guest shoppingSession-scoped
DELETE/cart/items/{line_key}Guest shoppingSession-scoped
POST/cart/clearGuest shoppingSession-scoped
POST/cart/couponsGuest shoppingCoupon validity rules
DELETE/cart/coupons/{code}Guest shoppingSession-scoped
POST/cart/shippingGuest shoppingSession-scoped
POST/cart/billingGuest shoppingSession-scoped
POST/checkoutGuest checkoutStock, coupon and payment validation
GET/checkout/optionsGuest checkoutGateway isAvailable($context)
POST/checkout/shippingGuest checkoutNone needed — rate quote only
POST/reviewsShopper submissionAuto-approval decided by ambikly_review_auto_approve; IP recorded
GET/products/{id}/reviewsStorefront displayApproved reviews only
GET/products/{id}/reviews/summaryStorefront displayApproved reviews only
GET/tagsStorefront filteringNone
GET/brandsStorefront filteringNone
GET/products/{id}/termsStorefront displayNone
GET/orders/{id}/invoiceEmailed linkOwner, staff or ?token= check, then an HTML 403
GET/orders/{id}/packing-slipPrintable linkOwner, staff or ?token= check, then an HTML 403
GET/downloads/{token}Emailed linkThe 32–64 character token is the credential; limits and expiry enforced
POST/stripe/webhookCalled by StripeStripe signature verification
GET/paypal/returnBuyer redirectPayPal order lookup
POST/paypal/webhookCalled by PayPalPayPal verification

ambikly-pro/v1 ​

Each of these registers only while its add-on is enabled and the license is valid.

MethodRouteAdd-on
POST/cart/gift-cardsGift Cards
DELETE/cart/gift-cards/{code}Gift Cards
POST/gift-cards/lookupGift Cards
GET/variation-swatchesAdvanced Variations
GET/recommendationsAI Recommendations
GET/filtered-productsAJAX Filters
GET/compareCompare
GET/checkout/order-bumpsOrder Bumps
POST/checkout/order-bumps/{id}/acceptOrder Bumps
DELETE/checkout/order-bumps/{id}/declineOrder Bumps
POST/licenses/activateLicense Pro
POST/licenses/deactivateLicense Pro
POST/licenses/checkLicense Pro
GET/updates/{slug}License Pro
POST/popup-leadsPopup Campaigns
POST/upsell/acceptPost-Purchase Upsells
POST/upsell/declinePost-Purchase Upsells
GET/badgesProduct Badges
GET/quick-view/{id}Quick View
GET/size-chartSize Chart
GET/smart-searchSmart Search
GET/wishlistWishlist
POST/wishlist/itemsWishlist
DELETE/wishlist/items/{id}Wishlist

Notes on specific routes ​

POST /gift-cards/lookup takes a code and returns its balance with no authentication. Gift card codes are the credential; treat guessing as the threat model and keep codes long.

GET /downloads/{token} is the entire digital delivery mechanism. The token is matched against [a-f0-9]{32,64}, and download limits and expiry are enforced in the handler. Anyone with the token can download the file — that is how emailed download links work.

POST /upsell/accept charges the payment method already stored against an order. Ownership is established from the order's own state, not from the caller's session.

GET /orders/{id}/invoice and GET /orders/{id}/packing-slip accept a token query parameter that substitutes for being logged in. Both return an HTML error page rather than JSON on failure, so a monitoring check that only looks at the status code will see a correct 403 or 404.

Next ​

Hooks & filters covers reacting to what these endpoints do from PHP.