The products API manages the merchandise catalog. Products can be searched by name or barcode, created with automatic price calculation (cost + margin = sale price + IVA), and operated offline with automatic sync. All write endpoints require theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Carlos-Gnd/FERRED-Inventario-y-Ventas/llms.txt
Use this file to discover all available pages before exploring further.
ADMIN or BODEGA role, while read endpoints are accessible to all authenticated roles.
Base URL: https://server-production-3252.up.railway.app
When the server cannot reach the cloud database, read operations fall back to the local SQLite replica transparently. For creates and updates, the operation is saved locally with a temporary negative ID and synced automatically when connectivity is restored.
GET /api/productos
Returns an array of active products, optionally filtered and including per-branch stock. Required role: Any authenticated user (ADMIN, CAJERO, BODEGA)
Query parameters
Free-text search. Matches against
nombre (case-insensitive) and codigoBarras.Filter to products belonging to this category ID.
When
true, returns only products where current stock is at or below the minimum threshold (stockActual <= stockMinimo, or per-branch stock when sucursalId is provided).Include per-branch stock (
cantidad, minimo) for this branch. Defaults to the authenticated user’s own sucursalId. Users can only query their own branch.Response
Array of product objects.Unique product ID.
Product name.
Barcode (unique).
Unit type:
UNIDAD, CAJA, PESO, MEDIDA, or LOTE.ID of the associated category.
Purchase cost.
Margin percentage used to calculate sale price.
Sale price before IVA.
Sale price including 13% IVA (when
tieneIva is true).Whether IVA applies. Defaults to
true.Aggregate stock across all branches.
Minimum stock threshold for low-stock alerts.
Whether the product is active. Always
true in list results.Present only when
sucursalId is resolved. Per-branch stock entry.list products
GET /api/productos/barcode/:codigo
Look up a single active product by its barcode. Useful at point of sale when a scanner reads a barcode. Required role: Any authenticated userPath parameters
The barcode string to look up. Must match the
codigoBarras field exactly.Response
Single product object withcategoria included (same shape as the list response), or 404 if not found.
GET /api/productos/:id/stock/:sucursalId
Returns the stock record for a specific product at a specific branch. Required role:ADMIN, CAJERO, or BODEGA
Users can only query stock for their own branch. Requests for a different branch’s stock return
403.Path parameters
Product ID.
Branch ID.
Response
Product ID.
Branch ID.
Current stock quantity at this branch. Returns
0 if no stock record exists yet.Minimum threshold at this branch. Returns
0 if no stock record exists yet.POST /api/productos
Creates a new product. IfprecioCompra and porcentajeGanancia are both provided, precioVenta and precioConIva are calculated automatically.
Required role: ADMIN or BODEGA
Price calculation:
precioVenta = precioCompra × (1 + porcentajeGanancia / 100)(rounded to 2 decimal places)precioConIva = precioVenta × 1.13whentieneIvaistrue, otherwise equalsprecioVenta
Request body
Product name. Minimum 2 characters.
ID of the category to associate. Must be a positive integer.
Barcode string. Must be globally unique.
Unit type. One of:
UNIDAD, CAJA, PESO, MEDIDA, LOTE.Purchase cost. Must be ≥ 0.
Margin percentage (e.g.
30 for 30%). Must be ≥ 0. Used with precioCompra for automatic price calculation.Sale price before IVA. Overridden by automatic calculation when
precioCompra and porcentajeGanancia are both provided.Whether 13% IVA applies to this product.
Initial stock quantity. Must be a non-negative integer.
Minimum stock threshold for low-stock alerts. Must be a non-negative integer.
Response
Confirmation message:
"Producto creado".The newly created product (same shape as list response, with
categoria included).create product
PUT /api/productos/:id
Partially updates an existing product. Only the fields included in the request body are updated. Price recalculation applies when bothprecioCompra and porcentajeGanancia are present in the update payload.
Required role: ADMIN or BODEGA
Path parameters
ID of the product to update.
Request body
All fields are optional (partial update). See POST /api/productos for field definitions.Response
Confirmation:
"Producto actualizado" (or "Producto actualizado offline" in offline mode).The updated product object. Not present in offline mode.
DELETE /api/productos/:id
Soft-deletes a product by settingactivo = false. The product is hidden from all list and barcode endpoints but its data is preserved for historical invoice records.
Required role: ADMIN only
Path parameters
ID of the product to deactivate. If the ID is negative (a locally-pending offline product), the pending local record is removed entirely instead.
Response
"Producto desactivado" (online) or "Producto eliminado offline" / "Producto eliminado localmente" (offline).POST /api/productos/:id/descontar-stock
Decrements stock for a product at a specific branch. Used at point of sale when processing a sale. Runs in a database transaction to prevent overselling. Required role:ADMIN or CAJERO
Path parameters
ID of the product whose stock to decrement.
Request body
Quantity to deduct. Must be a positive number.
Branch from which to deduct stock.
Response
Confirmation:
"Stock descontado" (or "Stock actualizado offline").Remaining stock at the branch after the deduction. Not present in offline mode.
Error responses
| Status | Condition |
|---|---|
400 | cantidad is missing or ≤ 0, or sucursalId is missing. |
409 | Insufficient stock. Response includes disponible, solicitado, and sucursalId. |