Appearance
public-storefront
14 endpoints.
GET /api/v1/public/storefront/resolve
Resolve Site
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
domain | query | yes | string | |
x-storefront-secret | header | no |
200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/public/storefront/config
Get Config
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no |
200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/auth/send-otp
Send Otp
Generate a 6-digit OTP, store its bcrypt hash, and email it.
Always returns 200 regardless of whether the email exists — prevents account enumeration. If no customer matches, a bare AccCustomer row is created (email only, status=active) so the OTP flow works for new shoppers too.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no |
Request body
json
{
"properties": {
"email": {
"type": "string",
"maxLength": 255,
"minLength": 3,
"title": "Email"
}
},
"type": "object",
"required": [
"email"
],
"title": "SendOtpIn"
}200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/auth/verify-otp
Verify Otp
Verify a 6-digit OTP and return a JWT + customer profile.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no |
Request body
json
{
"properties": {
"email": {
"type": "string",
"maxLength": 255,
"minLength": 3,
"title": "Email"
},
"code": {
"type": "string",
"maxLength": 6,
"minLength": 6,
"title": "Code"
}
},
"type": "object",
"required": [
"email",
"code"
],
"title": "VerifyOtpIn"
}200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/public/storefront/auth/me
Auth Me
Return the authenticated customer's profile, or 401.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
authorization | header | no | ||
x-storefront-secret | header | no |
200 — Successful Response
json
{
"properties": {
"email": {
"type": "string",
"title": "Email"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name"
},
"phone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Phone"
},
"customer_group": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Customer Group"
},
"is_reseller": {
"type": "boolean",
"title": "Is Reseller",
"default": false
}
},
"type": "object",
"required": [
"email"
],
"title": "StorefrontCustomerInfo"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/auth/login
Login
Authenticate with the same email+password as the portal (User table). Cross-DB: opens the portal site's session to verify credentials, then finds/creates an AccCustomer in the storefront site's DB.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no |
Request body
json
{
"properties": {
"email": {
"type": "string",
"maxLength": 255,
"minLength": 3,
"title": "Email"
},
"password": {
"type": "string",
"minLength": 1,
"title": "Password"
}
},
"type": "object",
"required": [
"email",
"password"
],
"title": "LoginIn"
}200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/auth/sso-exchange
Sso Exchange
Exchange a valid portal JWT for a storefront JWT — enables SSO from the portal to the storefront without re-entering credentials.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no |
Request body
json
{
"properties": {
"portal_token": {
"type": "string",
"title": "Portal Token"
}
},
"type": "object",
"required": [
"portal_token"
],
"title": "SsoExchangeIn"
}200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/public/storefront/reseller/users
List Reseller Users
The signed-in reseller's own end-users, for the checkout's "who is this order for?" picker.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
authorization | header | no | ||
x-storefront-secret | header | no |
200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/reseller/users
Create Reseller User From Storefront
Create a new end-user under the SIGNED-IN reseller, from the shop.
Mirrors app.api.reseller_settings.create_reseller_user — portal login (User + Tenant + owner Membership) on the portal site, AccCustomer with customer_group="Reseller User" + reseller_id on the books site — the difference being that this router is cross-site by construction (its site is the books site, given explicitly), so both DBs are opened here rather than one coming from Depends(get_db).
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
authorization | header | no | ||
x-storefront-secret | header | no |
Request body
json
{
"properties": {
"name": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"title": "Name"
},
"email": {
"type": "string",
"maxLength": 255,
"minLength": 3,
"title": "Email"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Phone"
},
"password": {
"anyOf": [
{
"type": "string",
"maxLength": 200,
"minLength": 8
},
{
"type": "null"
}
],
"title": "Password"
}
},
"type": "object",
"required": [
"name",
"email"
],
"title": "NewResellerEndUserIn"
}201 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/public/storefront/pages/{slug}
Get Page
One enabled content page's full HTML body, for storefront-web's /[slug] route. 404 if the page isn't a known standard page, isn't built, or is disabled.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
slug | path | yes | string | |
site | query | yes | string | |
x-storefront-secret | header | no |
200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/public/storefront/catalogue
Get Catalogue
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no | ||
authorization | header | no |
200 — Successful Response
json
{
"type": "array",
"items": {
"properties": {
"item_code": {
"type": "string",
"title": "Item Code"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"image_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Image Url"
},
"category": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Category"
},
"product_line": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Product Line"
},
"price": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Price"
},
"currency": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Currency"
},
"requires_shipping": {
"type": "boolean",
"title": "Requires Shipping",
"default": false
},
"features": {
"items": {
"type": "string"
},
"type": "array",
"title": "Features",
"default": []
},
"feature_values": {
"anyOf": [
{
"additionalProperties": {
"type": "string"
},
"type": "object"
},
{
"type": "null"
}
],
"title": "Feature Values"
},
"badge": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Badge"
},
"setup_fee": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Setup Fee"
},
"video_url": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Video Url"
},
"video_caption": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Video Caption"
}
},
"type": "object",
"required": [
"item_code",
"name",
"description",
"image_url",
"category",
"product_line",
"price",
"currency"
],
"title": "CatalogueItem"
},
"title": "Response Get Catalogue Api V1 Public Storefront Catalogue Get"
}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/checkout
Checkout
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no | ||
authorization | header | no |
Request body
json
{
"properties": {
"items": {
"items": {
"properties": {
"item_code": {
"type": "string",
"title": "Item Code"
},
"qty": {
"type": "number",
"exclusiveMinimum": 0,
"title": "Qty"
}
},
"type": "object",
"required": [
"item_code",
"qty"
],
"title": "CheckoutItemIn"
},
"type": "array",
"maxItems": 100,
"minItems": 1,
"title": "Items"
},
"email": {
"type": "string",
"maxLength": 255,
"title": "Email"
},
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 255
},
{
"type": "null"
}
],
"title": "Name"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"title": "Phone"
},
"shipping_option": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Shipping Option"
},
"shipping_address": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Shipping Address"
},
"origin": {
"type": "string",
"maxLength": 500,
"title": "Origin"
},
"recurring": {
"type": "boolean",
"title": "Recurring",
"default": false
},
"reseller_user_id": {
"anyOf": [
{
"type": "string",
"maxLength": 36
},
{
"type": "null"
}
],
"title": "Reseller User Id"
}
},
"type": "object",
"required": [
"items",
"email",
"origin"
],
"title": "CheckoutIn"
}200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}POST /api/v1/public/storefront/contact
Contact
Storefront "Get in Touch" enquiry — emails the site's own support inbox (branding.support_email) via the per-site SMTP overlay. Best-effort like every other send here: a disabled/misconfigured SMTP returns a clean 422 rather than 500, so the storefront can show a real message.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
site | query | yes | string | |
x-storefront-secret | header | no |
Request body
json
{
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"title": "Name"
},
"email": {
"type": "string",
"maxLength": 255,
"minLength": 3,
"title": "Email"
},
"subject": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"title": "Subject"
},
"message": {
"type": "string",
"maxLength": 5000,
"minLength": 1,
"title": "Message"
}
},
"type": "object",
"required": [
"name",
"email",
"message"
],
"title": "ContactIn"
}200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}GET /api/v1/public/storefront/orders/{token}
Order Status
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
token | path | yes | string | |
site | query | yes | string | |
x-storefront-secret | header | no |
200 — Successful Response
json
{}422 — Validation Error
json
{
"properties": {
"detail": {
"items": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
}