Other
Category: Store
Base URL: /store/analytics
Authentication: Mixed
Routes: 26 routes documented
Overview#
This section documents 26 API routes for other.
Quick Reference#
| Method | Endpoint | Description |
|---|---|---|
| GET | /store/analytics/config |
GET /store/analytics/config Returns analytics configuration ... |
| POST | /store/attentive/opt-in |
POST /store/attentive/opt-in Explicit SMS opt-in when custom... |
| GET | /store/banners |
GET /store/banners?store_handle=vnsh Returns the banners tha... |
| GET | /store/bundle-products/:id |
No description |
| GET | /store/content-pages |
GET /store/content-pages?slug=shipping-policy Returns one op... |
| GET | /store/custom |
No description |
| POST | /store/flow-builder/accept |
No description |
| GET | /store/flow-builder/button/:buttonId |
// GET /store/flow-builder/button/:buttonId - Get button det... |
| POST | /store/flow-builder/decline |
No description |
| POST | /store/flow-builder/init |
No description |
| POST | /store/flow-builder/init-with-order |
No description |
| GET | /store/flow-builder/receipt |
// GET /store/flow-builder/receipt - Get receipt for current... |
| GET | /store/membership/status |
GET /store/membership/status?order_id= |
| POST | /store/oauth/token |
No description |
| POST | /store/payment-intent/update-amount |
POST /store/payment-intent/update-amount Updates a Stripe Pa... |
| GET | /store/payment-methods/:account_holder_id |
GET /store/payment-methods/:account_holder_id List the saved... |
| POST | /store/payment-methods/:account_holder_id |
POST /store/payment-methods/:account_holder_id Save (vault) ... |
| DELETE | /store/payment-methods/:account_holder_id/:method_id |
DELETE /store/payment-methods/:account_holder_id/:method_id ... |
| GET | /store/payment-sessions |
GET /store/payment-sessions List payment sessions for a coll... |
| DELETE | /store/payment-sessions |
DELETE /store/payment-sessions Delete specific payment sessi... |
| POST | /store/payment/confirm-with-token |
POST /store/payment/confirm-with-token Stripe's recommended ... |
| GET | /store/products/:id/pdp-sections |
GET /store/products/:id/pdp-sections Get visible PDP section... |
| GET | /store/products/:id/reviews |
No description |
| GET | /store/products/:id/subscription-offer |
No description |
| POST | /store/products/:id/track-view |
POST /store/products/:id/track-view Storefront product-page ... |
| POST | /store/reviews |
No description |
| GET | /store/sites/by-domain |
No description |
| POST | /store/tracking/events |
No description |
GET Store Analytics Config#
Endpoint: GET /store/analytics/config
Authentication: Customer (Optional)
Description#
GET /store/analytics/config Returns analytics configuration for frontend SDK initialization Only exposes public-safe credentials (appId, trackingDomain) Never exposes API keys or secrets
Response#
Success:
{
provider,
config,
}Also returns:
{
provider,
config,
}Also returns:
{
provider,
config,
}Error (500):
{
error,
message,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/analytics/config' \
-H 'Content-Type: application/json'POST Store Attentive Opt-in#
Endpoint: POST /store/attentive/opt-in
Authentication: Customer (Optional)
Description#
POST /store/attentive/opt-in Explicit SMS opt-in when customer checks the "Get 10% off" checkbox. This is the ONLY place Attentive sync should happen during checkout. Returns the phone that was synced so frontend can track it and avoid duplicates.
Request Body#
This route does not declare a validation schema, so the accepted fields are not derivable from the source. Check the handler before relying on a particular body.
Response#
Success:
{
success,
skipped,
message,
}Also returns:
{
success,
skipped,
message,
}Also returns:
{
success,
syncedPhone,
isNew,
}Also returns:
{
success,
error,
}Error (400):
{
error,
}Error (500):
{
success,
error,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/attentive/opt-in' \
-H 'Content-Type: application/json'GET Store Banners#
Endpoint: GET /store/banners
Authentication: Customer (Optional)
Description#
GET /store/banners?store_handle=vnsh Returns the banners that are live RIGHT NOW for one storefront, highest priority first. Scheduling lives in the banner module (see resolveWindow): a banner uses its own window when set, otherwise it inherits its CAMPAIGN's window — OmniCart promotions carry no dates at all, only campaigns do — and a banner with neither is treated as inactive rather than always-on. The active/inactive decision is made HERE rather than by the storefront so a cached client bundle can never keep showing a finished sale.
Response#
Success:
{
banners,
}Also returns:
{
banners,
}Also returns:
{
banners,
}Also returns:
{
banners,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/banners' \
-H 'Content-Type: application/json'GET Store Bundle-products :id#
Endpoint: GET /store/bundle-products/:id
Authentication: Customer (Optional)
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Id identifier |
Response#
Success:
{
bundle_product,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/bundle-products/:id' \
-H 'Content-Type: application/json'GET Store Content-pages#
Endpoint: GET /store/content-pages
Authentication: Customer (Optional)
Description#
GET /store/content-pages?slug=shipping-policy Returns one operator-edited page, or null. WHY NULL AND NOT 404 -------------------- { page: null } with a 200 is the contract. The storefront still ships the original copy for each of these routes and falls back to it whenever this returns null, so an unseeded database, a typo'd slug and a page that has been deleted all degrade to "the site looks exactly as it does today". A 404 would make the storefront choose between rendering an error page and swallowing an exception, and the wrong choice there is a blank policy page — which for legal copy is worse than stale copy. The published/unpublished decision is made HERE rather than by the storefront so a cached client bundle can never reveal a draft.
Response#
Success:
{
page,
}Also returns:
{
page,
}Also returns:
{
page,
preview_locked,
}Also returns:
{
page,
}Also returns:
{
page,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/content-pages' \
-H 'Content-Type: application/json'GET Store Custom#
Endpoint: GET /store/custom
Authentication: Customer (Optional)
Response#
The handler does not return an object literal, so the response shape is not derivable from the source.
Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/custom' \
-H 'Content-Type: application/json'POST Store Flow-builder Accept#
Endpoint: POST /store/flow-builder/accept
Authentication: Customer (Optional)
Request Body#
| Field | Type | Required |
|---|---|---|
button_id |
string | Yes |
cart_id |
string | No |
Response#
Success:
{
next_button,
redirect_url,
is_terminal,
}Error (400):
{
error,
}Error (404):
{
error,
}Error (400):
{
error,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/flow-builder/accept' \
-H 'Content-Type: application/json'GET Store Flow-builder Button :buttonId#
Endpoint: GET /store/flow-builder/button/:buttonId
Authentication: Customer (Optional)
Description#
// GET /store/flow-builder/button/:buttonId - Get button details
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
buttonId |
string | Yes | ButtonId identifier |
Response#
Success:
{
button,
session,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/flow-builder/button/:buttonId' \
-H 'Content-Type: application/json'POST Store Flow-builder Decline#
Endpoint: POST /store/flow-builder/decline
Authentication: Customer (Optional)
Request Body#
| Field | Type | Required |
|---|---|---|
button_id |
string | Yes |
Response#
Success:
{
next_button,
redirect_url,
is_terminal,
}Error (400):
{
error,
}Error (404):
{
error,
}Error (400):
{
error,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/flow-builder/decline' \
-H 'Content-Type: application/json'POST Store Flow-builder Init#
Endpoint: POST /store/flow-builder/init
Authentication: Customer (Optional)
Request Body#
| Field | Type | Required |
|---|---|---|
flow_id |
string | Yes |
cart_id |
string | No |
Response#
Success (201):
{
session,
entry_button,
}Error (400):
{
error,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/flow-builder/init' \
-H 'Content-Type: application/json'POST Store Flow-builder Init-with-order#
Endpoint: POST /store/flow-builder/init-with-order
Authentication: Customer (Optional)
Request Body#
| Field | Type | Required |
|---|---|---|
flow_id |
string | Yes |
cart_id |
string | Yes |
order_id |
string | Yes |
payment_collection_id |
string | Yes |
original_order_total |
number | Yes |
Response#
Success:
{
session,
entry_button,
}Error (400):
{
error,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/flow-builder/init-with-order' \
-H 'Content-Type: application/json'GET Store Flow-builder Receipt#
Endpoint: GET /store/flow-builder/receipt
Authentication: Customer (Optional)
Description#
// GET /store/flow-builder/receipt - Get receipt for current session
Response#
Success:
{
receipt,
}Error (400):
{
error,
}Error (404):
{
error,
}Error (400):
{
error,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/flow-builder/receipt' \
-H 'Content-Type: application/json'GET Store Membership Status#
Endpoint: GET /store/membership/status
Authentication: Customer (Optional)
Description#
GET /store/membership/status?order_id=
Response#
Success:
{
membership,
}Error (400):
{
message,
}Error (404):
{
message,
}Error (500):
{
message,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/membership/status' \
-H 'Content-Type: application/json'POST Store Oauth Token#
Endpoint: POST /store/oauth/token
Authentication: Customer (Optional)
Request Body#
| Field | Type | Required |
|---|---|---|
grant_type |
unknown | Yes |
client_id |
string | Yes |
client_secret |
string | Yes |
scope |
string | No |
Response#
Error (400):
{
error,
details,
}Error (401):
{
error,
message,
}Error (400):
{
error,
message,
}Error (500):
{
error,
message,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/oauth/token' \
-H 'Content-Type: application/json'POST Store Payment-intent Update-amount#
Endpoint: POST /store/payment-intent/update-amount
Authentication: Customer (Optional)
Description#
POST /store/payment-intent/update-amount Updates a Stripe PaymentIntent's amount without changing the clientSecret. This allows updating the cart total (e.g., after tax/shipping calculation) without remounting Stripe Elements and losing user input. Critical for Express Checkout flows (Apple Pay/Google Pay) where we need to update the amount based on shipping address changes (tax calculation). Uses custom StripeProviderService which extends the platform's Stripe provider with additional methods for PaymentIntent updates. Stripe allows updating PaymentIntent amounts as long as the status is 'requires_payment_method', 'requires_confirmation', or 'requires_action'.
Request Body#
This route does not declare a validation schema, so the accepted fields are not derivable from the source. Check the handler before relying on a particular body.
Response#
Success (200):
{
success,
updated,
amount,
message,
}Also returns (200):
{
success,
updated,
previousAmount,
newAmount,
status,
clientSecret,
}Error (400):
{
error,
}Error (404):
{
error,
}Error (500):
{
error,
}Error (400):
{
error,
currentStatus,
}Error (400):
{
error,
type,
}Error (500):
{
error,
message,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/payment-intent/update-amount' \
-H 'Content-Type: application/json'GET Store Payment-methods :account_holder_id#
Endpoint: GET /store/payment-methods/:account_holder_id
Authentication: Customer (Optional)
Description#
GET /store/payment-methods/:account_holder_id List the saved payment methods for the authenticated customer's account holder. Ownership is enforced (see resolveOwnedAccountHolder) — a customer can only ever list their OWN account holder's methods.
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
account_holder_id |
string | Yes | Account_holder_id identifier |
Response#
Success:
{
payment_methods,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/payment-methods/:account_holder_id' \
-H 'Content-Type: application/json'POST Store Payment-methods :account_holder_id#
Endpoint: POST /store/payment-methods/:account_holder_id
Authentication: Customer (Optional)
Description#
POST /store/payment-methods/:account_holder_id Save (vault) a payment method against the authenticated customer's account holder, so it can later be charged by reference (subscriptions read subscription.payment_context.payment_method_reference — the returned id is that reference). Provider-agnostic: this forwards to the payment module's createPaymentMethods, which delegates to the provider's optional savePaymentMethod hook. data is the PAN-free, provider-specific token payload the storefront collected client-side (Hyperswitch SDK payment_method / setup token, Stripe SetupIntent payment_method, …). No raw card data is handled here. ⚠️ Provider hook: the vendored Hyperswitch provider NOW implements savePaymentMethod — it mints/attaches the token payload to the account holder's HS customer and returns the vaulted method id. The 501 branch below is a defensive fallback: the payment module wrapper still returns {} (id: undefined) for ANY provider that lacks the hook, so we surface that as NOT_IMPLEMENTED rather than pretending a method was vaulted. For Hyperswitch it will not fire.
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
account_holder_id |
string | Yes | Account_holder_id identifier |
Request Body#
| Field | Type | Required |
|---|---|---|
data |
record | No |
Response#
Success (201):
{
payment_method,
reference,
}Error (501):
{
type,
message,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/payment-methods/:account_holder_id' \
-H 'Content-Type: application/json'DELETE Store Payment-methods :account_holder_id :method_id#
Endpoint: DELETE /store/payment-methods/:account_holder_id/:method_id
Authentication: Customer (Optional)
Description#
DELETE /store/payment-methods/:account_holder_id/:method_id Detach a saved payment method from the authenticated customer's account holder. Ownership of the account holder is enforced first (resolveOwnedAccountHolder) so a customer can never delete a method attached to another customer's account holder. Forwards to the payment module's deletePaymentMethods, which delegates to the provider's optional deletePaymentMethod hook. ⚠️ Provider hook: the vendored Hyperswitch provider NOW implements deletePaymentMethod and really detaches the method at the gateway. It ALSO enforces method ownership a second time inside the hook — it lists the account holder's own HS methods and refuses (NOT_FOUND) any method_id that is not among them, so a caller who owns this account holder still cannot delete a method belonging to another customer's HS customer. (Providers without the hook remain a silent 200 no-op.)
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
account_holder_id |
string | Yes | Account_holder_id identifier |
method_id |
string | Yes | Method_id identifier |
Response#
Success:
{
id,
object,
deleted,
}Example Request#
curl -X DELETE 'https://your-store.omnicart.cc/store/payment-methods/:account_holder_id/:method_id' \
-H 'Content-Type: application/json'GET Store Payment-sessions#
Endpoint: GET /store/payment-sessions
Authentication: Customer (Optional)
Description#
GET /store/payment-sessions List payment sessions for a collection with filters
Response#
Success:
{
sessions,
count,
collection_id,
}Error (400):
{
message,
}Error (500):
{
message,
error,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/payment-sessions' \
-H 'Content-Type: application/json'DELETE Store Payment-sessions#
Endpoint: DELETE /store/payment-sessions
Authentication: Customer (Optional)
Description#
DELETE /store/payment-sessions Delete specific payment sessions with retry logic
Response#
Success:
{
success,
deleted,
failed,
errors,
metadata,
}Error (400):
{
message,
}Error (400):
{
message,
}Error (500):
{
message,
error,
}Example Request#
curl -X DELETE 'https://your-store.omnicart.cc/store/payment-sessions' \
-H 'Content-Type: application/json'POST Store Payment Confirm-with-token#
Endpoint: POST /store/payment/confirm-with-token
Authentication: Customer (Optional)
Description#
POST /store/payment/confirm-with-token Stripe's recommended two-step confirmation flow for one-page checkouts: 1. Client creates ConfirmationToken (contains payment method + billing details) 2. Server creates PaymentIntent with FINAL amount (after tax calculation) 3. Server confirms payment using ConfirmationToken This avoids updating PaymentIntent amounts which can cause Elements to remount. Reference: https://docs.stripe.com/payments/accept-a-payment-deferred
Request Body#
This route does not declare a validation schema, so the accepted fields are not derivable from the source. Check the handler before relying on a particular body.
Response#
Success (200):
{
success,
paymentIntent,
}Error (400):
{
error,
}Error (404):
{
error,
}Error (400):
{
error,
}Error (500):
{
error,
}Error (400):
{
error,
type,
code,
}Error (400):
{
error,
type,
}Error (500):
{
error,
message,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/payment/confirm-with-token' \
-H 'Content-Type: application/json'GET Store Products :id Pdp-sections#
Endpoint: GET /store/products/:id/pdp-sections
Authentication: Customer (Optional)
Description#
GET /store/products/:id/pdp-sections Get visible PDP sections for a product (storefront) Reads from product.metadata.pdp_sections
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Id identifier |
Response#
Success:
{
sections,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/products/:id/pdp-sections' \
-H 'Content-Type: application/json'GET Store Products :id Reviews#
Endpoint: GET /store/products/:id/reviews
Authentication: Customer (Optional)
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Id identifier |
Response#
Success:
{
reviews,
count,
limit,
offset,
average_rating,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/products/:id/reviews' \
-H 'Content-Type: application/json'GET Store Products :id Subscription-offer#
Endpoint: GET /store/products/:id/subscription-offer
Authentication: Customer (Optional)
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Id identifier |
Response#
The handler does not return an object literal, so the response shape is not derivable from the source.
Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/products/:id/subscription-offer' \
-H 'Content-Type: application/json'POST Store Products :id Track-view#
Endpoint: POST /store/products/:id/track-view
Authentication: Customer (Optional)
Description#
POST /store/products/:id/track-view Storefront product-page view emitter. Publishes a product.viewed event onto the platform event bus; the existing attentive-product-viewed subscriber listens for it and pushes the "Product Viewed" custom event to Attentive. Why this route exists: product.viewed is NOT a built-in platform event. It only fires when this endpoint is hit, typically once per product page mount on the storefront. The Attentive subscriber maintains its own 5-minute in-memory dedup per (product, customer) pair, so rapid page refreshes / re-mounts won't flood Attentive.
URL Parameters#
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Id identifier |
Request Body#
| Field | Type | Required |
|---|---|---|
variant_id |
string | No |
Response#
Success:
{
success,
}Also returns:
{
success,
}Error (400):
{
error,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/products/:id/track-view' \
-H 'Content-Type: application/json'POST Store Reviews#
Endpoint: POST /store/reviews
Authentication: Customer (Optional)
Request Body#
| Field | Type | Required |
|---|---|---|
title |
string | No |
content |
string | Yes |
rating |
number | Yes |
product_id |
string | Yes |
first_name |
string | Yes |
last_name |
string | Yes |
Response#
The handler does not return an object literal, so the response shape is not derivable from the source.
Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/reviews' \
-H 'Content-Type: application/json'GET Store Sites By-domain#
Endpoint: GET /store/sites/by-domain
Authentication: Customer (Optional)
Response#
Success:
{
site,
}Also returns:
{
site,
}Example Request#
curl -X GET 'https://your-store.omnicart.cc/store/sites/by-domain' \
-H 'Content-Type: application/json'POST Store Tracking Events#
Endpoint: POST /store/tracking/events
Authentication: Customer (Optional)
Request Body#
This route does not declare a validation schema, so the accepted fields are not derivable from the source. Check the handler before relying on a particular body.
Response#
Success (202):
{
accepted,
event_id,
}Also returns (202):
{
accepted,
event_id,
}Error (400):
{
accepted,
reason,
}Error (400):
{
accepted,
reason,
}Example Request#
curl -X POST 'https://your-store.omnicart.cc/store/tracking/events' \
-H 'Content-Type: application/json'