Lens Pricing API Documentation
This document describes the lens pricing endpoints for managing optical lens prices by clusters and axes.Endpoint Details
Base URL:https://joptic.jethings.com
Required Headers
Authentication
All endpoints require store authentication via the@StoreId() decorator, which automatically extracts the store ID from the request context.
Get All Lens Clusters
Get all unique lens clusters available for the current store. Endpoint:GET /lens-pricing/clusters
Query Parameters
NoneSuccess Response
Response Fields
clusters(array) - Array of cluster objectsname(string) - Cluster name (e.g., “1.56 HMC”)itemCount(number) - Total number of items in each cluster
Cluster names exclude color information (e.g., “1.50 PhGy BB” becomes “1.50 BB”). Clusters are sorted numerically.
itemCount represents the total number of items in each cluster.Example Request
Possible Errors
401 Unauthorized- Missing or invalid authentication token403 Forbidden- User does not have access to the store500 Internal Server Error- Server error
Get Items with Pricing (Paginated)
Get all items with pricing for a specific cluster with pagination support. Endpoint:GET /lens-pricing/items
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
cluster | string | ✅ Yes | — | The lens cluster, e.g., “1.56 HMC” |
type | string | No | sell | Price list type: “sell” or “buy” |
page | number | No | 1 | Page number (min: 1) |
limit | number | No | 10 | Items per page (min: 1, max: 100) |
Success Response
Response Fields
cluster(string) - The cluster namepriceListType(string) - The price list type used (“sell” or “buy”)priceList(object) - Price list informationid(string) - Price list IDname(string) - Price list name
data(array) - Array of items with pricingitemId(string) - Item IDitemName(string) - Full item namesph(string) - Sphere value with sign (e.g., “+0.25”)cyl(string) - Cylinder value with sign (e.g., “-0.50”)price(number | null) - Price value or null if not setpriceId(string | null) - Price ID if price existshasPrice(boolean) - Whether a price exists for the itemisActive(boolean) - Whether the item is active
pagination(object) - Pagination metadataitemsWithPrice(number) - Count of items with pricesitemsWithoutPrice(number) - Count of items without prices
Items are sorted by SPH and CYL values numerically.
sph and cyl values include their signs (e.g., “+0.25”, “-0.50”). price is null if no price is set for the item. hasPrice indicates whether a price exists for the item.Example Request
Possible Errors
400 Bad Request- Missing or invalid cluster parameter401 Unauthorized- Missing or invalid authentication token403 Forbidden- User does not have access to the store404 Not Found- Price list not found for the specified type500 Internal Server Error- Server error
Get Items as Table/Matrix Format
Get items with pricing organized in a matrix format grouped by sign combinations. This endpoint is optimized for table rendering in the frontend. Endpoint:GET /lens-pricing/items/table
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
cluster | string | ✅ Yes | — | The lens cluster, e.g., “1.56 HMC” |
type | string | No | sell | Price list type: “sell” or “buy” |
format | string | No | record | Response format: “record” or “array” |
Success Response
Response Fields
cluster(string) - The cluster namepriceListType(string) - The price list type used (“sell” or “buy”)priceList(object) - Price list informationmatrices(object) - Price matrices grouped by sign combinationspp(object) - Positive SPH (+) / Positive CYL (+) matrixnn(object) - Negative SPH (-) / Negative CYL (-) matrixnp(object) - Negative SPH (-) / Positive CYL (+) matrixaxes(object) - Available axis valuessph(array) - Available SPH values (sorted numerically)cyl(array) - Available CYL values (sorted numerically)
prices(object) - Price map using"sph|cyl"keys
Sign Combinations
pp
Positive SPH (+) / Positive CYL (+)
Both values are positive
Both values are positive
nn
Negative SPH (-) / Negative CYL (-)
Both values are negative
Both values are negative
np
Negative SPH (-) / Positive CYL (+)
Mixed signs
Mixed signs
Only non-empty matrices are included in the response. Price keys use the format
"sph|cyl" with absolute values (e.g., "0.25|0.5"). Prices are null if not set for that item. Axes arrays are sorted numerically in ascending order. This format is optimized for rendering pricing tables in the frontend.Example Request
Possible Errors
400 Bad Request- Missing or invalid cluster parameter401 Unauthorized- Missing or invalid authentication token403 Forbidden- User does not have access to the store404 Not Found- Price list not found for the specified type500 Internal Server Error- Server error
Set/Update Item Prices by Cluster and Axes
Set or update prices for multiple lens items in bulk. Uses database transactions and bulk operations for optimal performance. This endpoint supports two different price formats for maximum flexibility. Endpoint:POST /lens-pricing/items/prices
Request Body
The endpoint accepts two different price formats:| Field | Type | Required | Description |
|---|---|---|---|
cluster | string | ✅ Yes | The lens cluster, e.g., “1.56 HMC” |
type | string | ✅ Yes | Price list type: “sell” or “buy” |
signCombo | string | ✅ Yes | Sign combination: “pp”, “nn”, or “np” |
prices | object or array | ✅ Yes | Price data in either Record format (object) or Array format (array) |
Format 1: Record Format (Legacy - Still Supported)
Theprices field is an object mapping "sph|cyl" keys to price values:
prices(object) - Map of"sph|cyl"to price value- Key format:
"<sph>|<cyl>"(e.g.,"0|0","0.25|0.5") - Value: Price as a number
- Key format:
Price keys use absolute values in the format
"sph|cyl" (e.g., "0.25|0.5" means SPH=0.25, CYL=0.5). Values are numbers representing the price.Format 2: Array Format (New - Recommended)
Theprices field is an array of price point objects:
prices(array) - Array of price point objectsx(number) - Sphere (SPH) valuey(number) - Cylinder (CYL) valuevalue(number) - Price value
The endpoint automatically normalizes both formats internally. Array format is converted to Record format before processing, ensuring both formats produce identical results. Empty arrays or empty objects are allowed (will result in 0 updates/inserts).
Success Response
Response Fields
success(boolean) - Indicates if the operation was successfulcluster(string) - The cluster that was updatedsignCombo(string) - The sign combination that was updatedpriceListId(string) - ID of the price list that was modifiedupdated(number) - Count of existing prices that were updatedinserted(number) - Count of new prices that were inserted
Example Requests
Example 1: Using Array Format (Recommended)
Example 2: Using Record Format (Legacy)
This endpoint uses database transactions for atomicity and bulk operations for optimal performance. It’s efficient for updating hundreds of prices at once with a single query to fetch existing prices and parallel updates using
Promise.all. Prices are set per cluster and sign combination, and the endpoint automatically matches items based on their SPH/CYL values and signs.Format Conversion
The endpoint automatically normalizes both formats internally:- Array Format → Converted to Record format:
{x: 0.0, y: 0.0, value: 800}→{"0|0": 800} - Record Format → Passed through unchanged
Possible Errors
400 Bad Request- Validation errors (invalid cluster, type, signCombo, or request body structure)401 Unauthorized- Missing or invalid authentication token403 Forbidden- User does not have access to the store404 Not Found- No price list found for the specified type, or LENS product type not found500 Internal Server Error- Server error
Migration Guide
For Frontend Teams
The endpoint now supports two price formats. Here’s how to migrate: Old Format (Record) - Still Supported:Benefits of Array Format
Benefits of Array Format
- More intuitive structure (x, y coordinates)
- Easier to iterate and manipulate
- Better for form inputs and data grids
- More readable in code
Backward Compatibility
Backward Compatibility
- Both formats are fully supported
- No breaking changes
- Can migrate gradually
- Record format will continue to work indefinitely
Common Concepts
Cluster Format
A cluster represents a lens type defined by:Indice
Indice
Indice - The refractive index
Examples: “1.56”, “1.50”, “1.67”
Examples: “1.56”, “1.50”, “1.67”
Treatment
Treatment
Treatment - The lens treatment
Examples: “HMC” (Hard Multi-Coating), “BB” (Blue Block), “HC” (Hard Coating)
Examples: “HMC” (Hard Multi-Coating), “BB” (Blue Block), “HC” (Hard Coating)
"1.56 HMC" means:
- Indice: 1.56
- Treatment: HMC (Hard Multi-Coating)
- Color is excluded from cluster names
Item Name Format
Lens items follow this naming pattern:"1.56 HMC +0.00 -0.00"- No color, SPH=+0.00, CYL=-0.00"1.50 PhGy BB +0.25 -0.50"- Color=PhGy, SPH=+0.25, CYL=-0.50
Sign Combinations
Lens prescriptions can have different sign combinations:pp
pp (+sph/+cyl): Both sphere and cylinder values are positive
Example items: “+0.00 +0.00”, “+0.25 +0.50”
Example items: “+0.00 +0.00”, “+0.25 +0.50”
nn
nn (-sph/-cyl): Both sphere and cylinder values are negative
Example items: “-0.00 -0.00”, “-1.00 -0.50”
Example items: “-0.00 -0.00”, “-1.00 -0.50”
np
np (-sph/+cyl): Sphere is negative, cylinder is positive
Example items: “-0.00 +0.00”, “-0.50 +0.25”
Example items: “-0.00 +0.00”, “-0.50 +0.25”
Price Key Format
In the table/matrix format, prices use keys in the format:"0|0"- SPH=0, CYL=0 (regardless of sign)"0.25|0.5"- SPH=0.25, CYL=0.5 (absolute values)"1.25|1.5"- SPH=1.25, CYL=1.5 (absolute values)
Error Responses
All endpoints may return standard HTTP error codes:400 Bad Request- Invalid request parameters or body401 Unauthorized- Missing or invalid authentication token403 Forbidden- User does not have access to the store404 Not Found- Resource not found (price list, product type, etc.)500 Internal Server Error- Server error
Error Response Format
Usage Examples
Example 1: Get all clusters for a store
Example 2: Get first page of items for a cluster
Example 3: Get pricing table for a cluster
Example 4: Update prices using Array Format (Recommended)
Example 5: Update prices using Record Format (Legacy)
Performance Considerations
Pagination
Pagination
Always use pagination when fetching large lists of items to improve response times and reduce memory usage.
Bulk Updates
Bulk Updates
The
POST /items/prices endpoint is optimized for bulk operations. Use it to update multiple prices in a single request rather than making individual requests.Caching
Caching
Consider caching cluster lists as they change infrequently. This can significantly reduce API calls and improve performance.
Table Format
Table Format
Use the
/items/table endpoint for frontend table rendering. This format is optimized for matrix-based displays and reduces client-side processing.Version History
- v1.0 - Initial implementation with clusters, paginated items, table format, and bulk price updates
- v1.1 - Added Array format support for price updates (Record format still supported for backward compatibility)