Skip to main content
Products are standalone sellable items with an integer stock counter. Every time a product is included in a transaction, its stock is decremented automatically. All list and detail endpoints return only active (non-deleted) records.
Soft delete is used throughout. Deleting a product sets borrado_en to the current timestamp. The record is never physically removed from the database, and it will no longer appear in any list or detail response.

POST /api/productos

Create a new product. Authentication: Bearer JWT required
Required role: admin

Request body

nombre
string
required
Product name. Max 60 characters.
precio
number
required
Price in bolivianos. Must be >= 0. Stored as a two-decimal numeric.
stock
integer
required
Initial stock quantity. Must be an integer >= 0.
unidad
string
required
Unit of measure (e.g. kg, unidad, litro). Max 20 characters.

Response

Returns the created product object (201 Created).
id
string
Unique identifier generated with nanoid (10 characters).
nombre
string
Product name.
precio
string
Price as a decimal string (e.g. "45.50").
stock
integer
Current stock quantity.
unidad
string
Unit of measure.
creado_en
string (ISO 8601)
Creation timestamp.
actualizado_en
string (ISO 8601)
Last update timestamp.
borrado_en
string (ISO 8601) | null
Soft-delete timestamp. null for active products.

Example

curl -X POST http://localhost:3000/api/productos \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "nombre": "Arroz Premium",
    "precio": 45.50,
    "stock": 100,
    "unidad": "kg"
  }'
{
  "id": "aB3dE7fGhJ",
  "nombre": "Arroz Premium",
  "precio": "45.50",
  "stock": 100,
  "unidad": "kg",
  "creado_en": "2026-03-18T14:00:00.000Z",
  "actualizado_en": "2026-03-18T14:00:00.000Z",
  "borrado_en": null
}

GET /api/productos

Return all active products. Authentication: Bearer JWT required
Required role: any authenticated user

Request parameters

No parameters.

Response

Returns an array of product objects (200 OK). Only records where borrado_en IS NULL are included.

Example

curl http://localhost:3000/api/productos \
  -H "Authorization: Bearer <token>"
[
  {
    "id": "aB3dE7fGhJ",
    "nombre": "Arroz Premium",
    "precio": "45.50",
    "stock": 100,
    "unidad": "kg",
    "creado_en": "2026-03-18T14:00:00.000Z",
    "actualizado_en": "2026-03-18T14:00:00.000Z",
    "borrado_en": null
  }
]

GET /api/productos/:id

Return a single active product by ID. Authentication: Bearer JWT required
Required role: any authenticated user

Request parameters

id
string
required
The nanoid of the product.

Response

Returns the product object (200 OK), or 404 Not Found if the product does not exist or has been soft-deleted.

Example

curl http://localhost:3000/api/productos/aB3dE7fGhJ \
  -H "Authorization: Bearer <token>"
{
  "id": "aB3dE7fGhJ",
  "nombre": "Arroz Premium",
  "precio": "45.50",
  "stock": 100,
  "unidad": "kg",
  "creado_en": "2026-03-18T14:00:00.000Z",
  "actualizado_en": "2026-03-18T14:00:00.000Z",
  "borrado_en": null
}

PATCH /api/productos/:id

Partially update a product. All body fields are optional; only the fields you send are updated. Authentication: Bearer JWT required
Required role: admin

Request parameters

id
string
required
The nanoid of the product to update.
nombre
string
New product name. Max 60 characters.
precio
number
New price in bolivianos. Must be >= 0.
stock
integer
New stock quantity. Must be an integer >= 0.
unidad
string
New unit of measure. Max 20 characters.

Response

Returns the updated product object (200 OK). actualizado_en is always refreshed.

Example

curl -X PATCH http://localhost:3000/api/productos/aB3dE7fGhJ \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"stock": 80, "precio": 48.00}'

DELETE /api/productos/:id

Soft-delete a product. Authentication: Bearer JWT required
Required role: admin
This operation sets borrado_en and actualizado_en to the current timestamp. The product record is retained in the database and will no longer appear in list or detail responses.

Request parameters

id
string
required
The nanoid of the product to delete.

Response

Returns a confirmation message (200 OK).
message
string
Confirmation string, e.g. "Producto con ID aB3dE7fGhJ eliminado exitosamente (soft delete)".

Example

curl -X DELETE http://localhost:3000/api/productos/aB3dE7fGhJ \
  -H "Authorization: Bearer <token>"
{
  "message": "Producto con ID aB3dE7fGhJ eliminado exitosamente (soft delete)"
}

Build docs developers (and LLMs) love