The Products API is the foundation of Credith’s point-of-sale catalog. Every item that can be sold at a store must exist as a product record. Products carry pricing data — both cost (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/RoyGeova07/Credith/llms.txt
Use this file to discover all available pages before exploring further.
buyPrice) and sale price (sellPrice) — along with an optional minimum gain percentage that can be used to enforce margin rules at checkout. When a product is created, it is immediately registered in a store’s inventory with a configurable initial stock count. Archiving a product via DELETE performs a soft-delete: the record is never physically removed from the database, and it can be fully restored at any time using the recover endpoint.
List Products
Maximum number of products to return per page.
Number of records to skip before starting to return results. Used for pagination.
OWNER only. Filter products that belong to a specific store. ADMIN and EMPLOYEE users are automatically scoped to their assigned store and cannot override this.
Filter products by category name (case-sensitive match against the category’s
name field).When
true, returns archived (soft-deleted) products instead of active ones. Only OWNER users can view the global archived list without a storeId. For store-scoped views, archived reflects inventory isActive=false.- OWNER — sees all products across all stores unless
storeIdis provided. - ADMIN / EMPLOYEE — automatically scoped to their assigned store only.
Get Product by ID
404 if the product does not exist or has been globally archived.
Path parameter
The UUID of the product to retrieve.
Create Product
OWNER role. Both categoryId and storeId must reference existing records — the server validates both before creating anything.
Display name of the product. Must be unique across all products (enforced by a unique index on the
name column).The retail sale price of the product. Must be a non-negative number. Stored as
DECIMAL(16,8).UUID of the category to assign this product to. The category must already exist.
UUID of the store where the product’s initial inventory entry will be created.
A short description of the product. Required by the database (
allowNull: false on the description column). Cannot be omitted.The cost price (purchase price) of the product. Defaults to
0 if omitted or negative.Minimum acceptable profit margin percentage. Used as a soft business rule reference at checkout. Stored as
SMALLINT.URL pointing to the product’s image. Typically a Cloudinary-hosted URL obtained from the frontend upload widget.
The opening stock count for the product in the specified store. Defaults to
1 if omitted or less than zero.Update Product
productId in the request body must match the :id path parameter — the server returns 400 if they differ. Requires OWNER or ADMIN role.
You can optionally update the product’s store-level stock in the same request by supplying storeId and stock together.
The UUID of the product to update. Must match
productId in the body.Must be identical to the
:id path parameter.Updated display name for the product. Cannot be empty.
Updated retail price. Must be
>= 0.Updated product description.
Updated cost price. Defaults to
0 if omitted.Updated minimum gain percentage.
Updated image URL.
If provided, replaces the product’s entire category assignment with this single category (uses
setCategories). The category must exist.If provided alongside
stock, the inventory record for this product in the given store will be updated. Must be provided together with stock.New stock count for the product at
storeId. Must be >= 0. Requires storeId to also be present.Archive Product (Soft-Delete)
storeId query parameter is provided.
UUID of the product to archive.
- Optional for OWNER — archives the product only from the specified store (sets
isActive=falseon thestores_inventoriesrow). The product remains visible in other stores. - Required for ADMIN — ADMIN users must always provide
storeId; they cannot perform a global archive. - If omitted and the caller is OWNER, the product is globally archived via a Sequelize paranoid soft-delete (sets
deletedAt).
Archived products are never physically removed from the database. The soft-delete sets a
deleted_at timestamp (global archive) or sets isActive=false on the inventory row (store-level archive). All historical invoice data referencing the product remains intact. Use POST /api/products/:id/recover to restore them.Recover Product
storeId is supplied.
UUID of the product to restore.
If provided, restores the product only within that store’s inventory (sets
isActive=true). If omitted, performs a global restore via Sequelize’s restore(), clearing the deleted_at timestamp.Product Object
Unique identifier for the product. Auto-generated as UUIDv4.
Display name of the product. Unique across all products.
The retail price of the product, returned as a decimal string with 8 decimal places (e.g.
"45.00000000"). Stored as DECIMAL(16,8).The purchase/cost price. Defaults to
0.00000000. Stored as DECIMAL(16,8).Short description of the product.
Minimum profit margin percentage. May be
null if not set.URL to the product’s image. May be
null if not set.Whether the product is currently active. Managed through archive/recover operations.
Error Responses
| Status | Meaning |
|---|---|
400 | Missing required field, invalid price, mismatched productId, or invalid stock value |
401 | Request is not authenticated (missing or invalid session token) |
403 | Role is not permitted to perform the action (e.g., ADMIN attempting a global archive) |
404 | Product, category, store, or inventory record not found |
500 | Unexpected server error |