Skip to main content

Price List API Documentation

This document describes the price list management endpoints for creating, reading, updating, and deleting price lists in the optical store system.

Endpoint Details

Base URL: https://joptic.jethings.com

Required Headers

x-store-id: <store_id>
Authorization: Bearer <token>

Authentication

All endpoints require user authentication. The user ID is extracted from the JWT token (req.user.sub), and store access is validated via the @StoreId() decorator.

Rate Limiting

Endpoints are protected with rate limiting:
  • GET endpoints: 60 requests per minute (long throttle)
  • POST endpoints: 10 requests per minute (medium throttle)
  • PUT endpoints: 20 requests per minute (medium throttle)
  • DELETE endpoints: 3 requests per minute (short throttle)

Get All Price Lists

Retrieve a paginated list of price lists for the current store. Endpoint: GET /price-lists

Query Parameters

ParameterTypeRequiredDefaultDescription
searchstringNoSearch term to filter price lists by name
pagenumberNo1Page number (min: 1)
limitnumberNo10Items per page (min: 1, max: 100)
sortBystringNocreatedAtField to sort by
sortOrderstringNodescSort order: “asc” or “desc”
isActivebooleanNoFilter by active status (currently not implemented)

Success Response

{
  "data": [
    {
      "id": "price_list_123",
      "storeId": "store_456",
      "name": "Wholesale Prices",
      "createdAt": "2024-01-15T10:30:00Z",
      "customers": 0,
      "isActive": true,
      "itemsCount": 150
    },
    {
      "id": "price_list_124",
      "storeId": "store_456",
      "name": "Retail Prices",
      "createdAt": "2024-01-14T09:20:00Z",
      "customers": 0,
      "isActive": true,
      "itemsCount": 200
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 5,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}

Response Fields

  • id (string) - Unique identifier for the price list
  • storeId (string) - ID of the store that owns this price list
  • name (string) - Name of the price list
  • createdAt (Date) - Timestamp when the price list was created
  • customers (number) - Number of customers associated (currently always 0)
  • isActive (boolean) - Whether the price list is active
  • itemsCount (number) - Total number of items with prices in this list
Results are paginated for performance. Search is case-insensitive and matches price list names. Default sorting is by creation date (newest first).

Example Request

curl -X GET "https://joptic.jethings.com/price-lists?search=wholesale&page=1&limit=20&sortBy=name&sortOrder=asc" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>"

Possible Errors

  • 401 Unauthorized - Missing or invalid authentication token
  • 403 Forbidden - User does not have access to the store
  • 500 Internal Server Error - Server error

Create Price List

Create a new price list for the current store. Endpoint: POST /price-lists

Request Body

FieldTypeRequiredDescription
namestring✅ YesName of the price list (max: 255)
isBuyingbooleanNoWhether this is a buying/purchase price list (default: false)
isSellingbooleanNoWhether this is a selling price list (default: false)
descriptionstringNoDescription of the price list (max: 1000)

Request Body Example

{
  "name": "Wholesale Buying Prices",
  "isBuying": true,
  "isSelling": false,
  "description": "Price list for purchasing from suppliers"
}

Success Response

{
  "id": "price_list_123",
  "storeId": "store_456",
  "name": "Wholesale Buying Prices",
  "createdAt": "2024-01-15T10:30:00Z",
  "customers": 0,
  "isActive": true,
  "itemsCount": 0
}

Example Request

curl -X POST https://joptic.jethings.com/price-lists \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Retail Selling Prices",
    "isSelling": true,
    "isBuying": false,
    "description": "Standard retail prices for customers"
  }'
A price list can be both buying and selling (set both flags to true). The price list is automatically set as active upon creation and automatically linked to the current store. User must have access to the store (validated via user-store relation).

Possible Errors

  • 400 Bad Request - Validation errors (missing name, invalid field values)
  • 401 Unauthorized - Missing or invalid authentication token
  • 403 Forbidden - User does not have access to the store
  • 500 Internal Server Error - Server error

Update Price List

Update an existing price list. Endpoint: PUT /price-lists/:id

Path Parameters

ParameterTypeRequiredDescription
idstring✅ YesThe price list ID

Request Body

All fields are optional (partial updates supported):
FieldTypeRequiredDescription
namestringNoNew name for the price list (max: 255)
isActivebooleanNoWhether the price list should be active
isBuyingbooleanNoWhether this is a buying price list
isSellingbooleanNoWhether this is a selling price list
descriptionstringNoNew description (max: 1000)

Request Body Example

{
  "name": "Updated Wholesale Prices",
  "isActive": true,
  "isBuying": true,
  "isSelling": false,
  "description": "Updated description"
}

Success Response

{
  "id": "price_list_123",
  "storeId": "store_456",
  "name": "Updated Wholesale Prices",
  "createdAt": "2024-01-15T10:30:00Z",
  "customers": 0,
  "isActive": true,
  "itemsCount": 150
}

Example Request

curl -X PUT https://joptic.jethings.com/price-lists/price_list_123 \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Name",
    "isActive": false
  }'
Only provided fields are updated (partial updates supported). The updatedAt timestamp is automatically set. Price list must exist, otherwise returns 404.

Possible Errors

  • 400 Bad Request - Validation errors
  • 401 Unauthorized - Missing or invalid authentication token
  • 404 Not Found - Price list with the given ID does not exist
  • 500 Internal Server Error - Server error

Delete Multiple Price Lists

Delete one or more price lists by their IDs. Endpoint: DELETE /price-lists

Request Body

FieldTypeRequiredDescription
idsarray<string>✅ YesArray of price list IDs to delete

Request Body Example

{
  "ids": [
    "price_list_123",
    "price_list_124",
    "price_list_125"
  ]
}

Success Response

{
  "message": "Successfully deleted 3 price list(s)",
  "deletedCount": 3
}

Example Request

curl -X DELETE https://joptic.jethings.com/price-lists \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": ["price_list_123", "price_list_124"]
  }'
This is a bulk delete operation. Only valid price list IDs are deleted (invalid IDs are ignored). Returns the count of successfully deleted price lists. This operation is permanent and cannot be undone. Rate limited to 3 requests per minute for safety.

Possible Errors

  • 400 Bad Request - No IDs provided or empty array
  • 401 Unauthorized - Missing or invalid authentication token
  • 404 Not Found - No valid price lists found to delete
  • 500 Internal Server Error - Server error

Common Concepts

Price List Types

Price lists can be categorized by their purpose:
Buying Price Lists (isBuying: true)
  • Used for purchasing items from suppliers
  • Represents the cost at which items are bought
  • Example: “Wholesale Buying Prices”, “Supplier Prices”
Selling Price Lists (isSelling: true)
  • Used for selling items to customers
  • Represents the price at which items are sold
  • Example: “Retail Prices”, “Customer Prices”
Both (isBuying: true, isSelling: true)
  • Can be used for both buying and selling
  • Less common but supported

Price List States

Active

Active (isActive: true)
Price list is currently in use

Inactive

Inactive (isActive: false)
Price list is disabled but not deleted

Store Association

  • Each price list is associated with a specific store
  • Users can only access price lists for stores they have access to
  • Price lists are automatically linked to the store when created

Error Responses

All endpoints may return standard HTTP error codes:
  • 400 Bad Request - Invalid request parameters or body
  • 403 Forbidden - User does not have access to the store
  • 404 Not Found - Resource not found (price list, store, etc.)
  • 429 Too Many Requests - Rate limit exceeded
  • 500 Internal Server Error - Server error

Error Response Format

{
  "statusCode": 404,
  "message": "Price list not found",
  "error": "Not Found"
}

Usage Examples

Example 1: Get all price lists with pagination

curl -X GET "https://joptic.jethings.com/price-lists?page=1&limit=10" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>"

Example 2: Search for price lists

curl -X GET "https://joptic.jethings.com/price-lists?search=wholesale&page=1&limit=20" \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>"

Example 3: Create a buying price list

curl -X POST https://joptic.jethings.com/price-lists \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Supplier Prices",
    "isBuying": true,
    "isSelling": false,
    "description": "Prices from our main supplier"
  }'

Example 4: Create a selling price list

curl -X POST https://joptic.jethings.com/price-lists \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Retail Prices",
    "isBuying": false,
    "isSelling": true,
    "description": "Standard retail prices"
  }'

Example 5: Update price list name and status

curl -X PUT https://joptic.jethings.com/price-lists/price_list_123 \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Retail Prices",
    "isActive": true
  }'

Example 6: Delete multiple price lists

curl -X DELETE https://joptic.jethings.com/price-lists \
  -H "x-store-id: your-store-id" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": ["price_list_123", "price_list_124"]
  }'

Best Practices

  • Use descriptive names that indicate the purpose (e.g., “Wholesale Buying”, “Retail Selling”)
  • Include the price list type in the name for clarity
  • Create separate price lists for buying and selling
  • Use descriptions to provide additional context
  • Keep inactive price lists for historical reference
  • Use pagination when fetching large lists
  • Delete operations are rate-limited, so batch deletions carefully
  • Always check for 404 errors when updating/deleting
  • Handle rate limit errors (429) with exponential backoff
  • Validate request bodies before sending
  • Store access is automatically validated
  • Users can only manage price lists for stores they have access to
  • Price list IDs are validated to prevent unauthorized access

After creating price lists, you can manage item prices using:
  • Item Price Endpoints (/item-price) - Set prices for individual items
  • Lens Pricing Endpoints (/lens-pricing) - Specialized endpoints for lens pricing by clusters
See the respective documentation files for more information about item pricing and lens pricing endpoints.

Version History

  • v1.0 - Initial implementation with CRUD operations
  • v1.1 - Added isBuying and isSelling flags for price list categorization
  • v1.2 - Added search functionality and improved pagination