Catálogo
Recursos para administrar tu catálogo: productos, servicios, alquileres, categorías, variantes y opciones, perfiles de precio y promociones.
El módulo de Catálogo agrupa los recursos que componen lo que vendés o alquilás. Todos comparten la misma estructura de endpoints CRUD —listado, detalle, alta, edición, baja y operaciones en lote— y se exponen bajo https://api.yo-facturo.com.
Cada recurso tiene su propio par de scopes: el sufijo :read habilita la lectura y :write la creación, edición y eliminación. La columna Requerido de cada tabla indica los campos obligatorios al crear el recurso.
Productos
Los productos son bienes físicos o digitales que vendés. Soportan control de stock, SKU y código de barras, variantes, perfiles de precio, tramos de precio por cantidad y promociones embebidas.
Endpoint base: /api/v1/products
Scopes: products:read, products:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 200. |
base_price | number | Sí | Precio base. minimum 0, maximum 999999999999.99. |
description | string | No | Descripción del producto. |
sku | string | No | Código interno (SKU). |
barcode | string | No | Código de barras. |
category_id | string | No | ID de la categoría a la que pertenece. |
cost | number | No | Costo del producto. minimum 0, maximum 999999999999.99. |
track_stock | boolean | No | Indica si se controla el stock. |
stock | integer | No | Stock disponible. minimum 0, maximum 999999999. |
total_stock | integer | No | Stock total. minimum 0, maximum 999999999. |
min_stock | integer | No | Stock mínimo de alerta. minimum 0, maximum 999999999. |
unit | string | No | Unidad de medida. |
status | string | No | enum: draft, published, paused, deleted, archived. |
images | array<string> | No | IDs o URLs de imágenes. |
attributes | object | No | Atributos personalizados. |
variants | array | object | No | Variantes del producto. |
has_variants | boolean | No | Indica si el producto tiene variantes. |
global_option_refs | array | No | Referencias a opciones globales. |
tags | array<string> | No | Etiquetas. |
seo | object | No | Metadatos SEO. |
shipping | object | No | Configuración de envío. |
tax_rate | number | No | Alícuota de impuesto. minimum 0, maximum 100. |
weight | number | No | Peso. minimum 0, maximum 999999999. |
dimensions | object | No | Dimensiones físicas. |
featured | boolean | No | Indica si el producto es destacado. |
price_history | array | No | Historial de precios. |
quantity_price_tiers | array<object> | No | Tramos de precio por cantidad (min_quantity requerido en cada tramo). |
promotions | array<object> | No | Promociones embebidas (name y promotion_type requeridos en cada una). |
pricing_composition | object | No | Composición de precio (costo de proveedor, impuestos aplicados, ganancia). |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/products/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/products/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/products/ | Crear un recurso |
PUT | /api/v1/products/{id}/ | Actualizar un recurso |
DELETE | /api/v1/products/{id}/ | Eliminar un recurso |
POST | /api/v1/products/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/products/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/products/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/products/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Remera algodón premium",
"base_price": 12500.00,
"description": "Remera de algodón peinado, corte regular.",
"sku": "REM-ALG-001",
"category_id": "66f1a2b3c4d5e6f7a8b9c0d1",
"cost": 6200.00,
"track_stock": true,
"stock": 120,
"unit": "unidad",
"tax_rate": 21,
"status": "published",
"tags": ["indumentaria", "algodon"]
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0e2",
"name": "Remera algodón premium",
"base_price": 12500.00,
"sku": "REM-ALG-001",
"category_id": "66f1a2b3c4d5e6f7a8b9c0d1",
"track_stock": true,
"stock": 120,
"status": "published"
}
}Servicios
Los servicios representan prestaciones que ofrecés: trabajos por hora, por proyecto o de precio fijo. Permiten definir duración, modalidad (presencial, remota o híbrida) y si requieren reserva previa.
Endpoint base: /api/v1/services
Scopes: services:read, services:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 200. |
description | string | No | Descripción del servicio. |
category_id | string | No | ID de la categoría a la que pertenece. |
price | number | No | Precio del servicio. minimum 0. |
base_price | number | No | Precio base. minimum 0. |
pricing_type | string | No | enum: fixed, hourly, project, custom. |
duration | integer | No | Duración del servicio. |
duration_unit | string | No | enum: minutes, hours, days, weeks. |
availability | object | No | Configuración de disponibilidad. |
location_type | string | No | enum: on_site, remote, hybrid. |
service_area | array<string> | No | Zonas donde se presta el servicio. |
images | array<string> | No | IDs o URLs de imágenes. |
requirements | array<string> | No | Requisitos previos. |
included_items | array<string> | No | Ítems incluidos. |
excluded_items | array<string> | No | Ítems no incluidos. |
tags | array<string> | No | Etiquetas. |
status | string | No | enum: draft, published, paused, deleted, archived. |
booking_required | boolean | No | Indica si requiere reserva previa. |
advance_booking_days | integer | No | Días de anticipación para reservar. minimum 0. |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/services/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/services/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/services/ | Crear un recurso |
PUT | /api/v1/services/{id}/ | Actualizar un recurso |
DELETE | /api/v1/services/{id}/ | Eliminar un recurso |
POST | /api/v1/services/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/services/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/services/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/services/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Consultoría contable mensual",
"description": "Asesoramiento contable e impositivo.",
"category_id": "66f1a2b3c4d5e6f7a8b9c0d3",
"price": 90000.00,
"pricing_type": "fixed",
"duration": 1,
"duration_unit": "days",
"location_type": "remote",
"booking_required": true,
"advance_booking_days": 2,
"status": "published"
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0e3",
"name": "Consultoría contable mensual",
"price": 90000.00,
"pricing_type": "fixed",
"location_type": "remote",
"status": "published"
}
}Alquileres
Los alquileres son bienes que ofrecés por un período de tiempo (hora, día, semana o mes). Permiten configurar depósito de garantía, tiempos mínimo y máximo, estado de disponibilidad, seguro y entrega.
Endpoint base: /api/v1/rentals
Scopes: rentals:read, rentals:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 200. |
description | string | No | Descripción del alquiler. |
category_id | string | No | ID de la categoría a la que pertenece. |
rental_price | number | No | Precio del alquiler. minimum 0, maximum 999999999999.99. |
base_price | number | No | Precio base. minimum 0, maximum 999999999999.99. |
time_unit | string | No | enum: hour, day, week, month. |
security_deposit | number | No | Depósito de garantía. minimum 0, maximum 999999999999.99. |
availability_status | string | No | enum: available, in_use, maintenance, unavailable. |
location | string | No | Ubicación del bien en alquiler. |
images | array<string> | No | IDs o URLs de imágenes. |
terms_conditions | string | No | Términos y condiciones del alquiler. |
min_time | integer | No | Tiempo mínimo de alquiler. minimum 1. |
max_time | integer | No | Tiempo máximo de alquiler. |
tags | array<string> | No | Etiquetas. |
features | array<string> | No | Características del bien. |
insurance_required | boolean | No | Indica si se requiere seguro. |
delivery_available | boolean | No | Indica si hay entrega a domicilio. |
status | string | No | enum: draft, published, paused, deleted, archived. |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/rentals/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/rentals/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/rentals/ | Crear un recurso |
PUT | /api/v1/rentals/{id}/ | Actualizar un recurso |
DELETE | /api/v1/rentals/{id}/ | Eliminar un recurso |
POST | /api/v1/rentals/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/rentals/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/rentals/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/rentals/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Proyector Full HD 3000 lúmenes",
"description": "Proyector para eventos y presentaciones.",
"category_id": "66f1a2b3c4d5e6f7a8b9c0d4",
"rental_price": 18000.00,
"time_unit": "day",
"security_deposit": 50000.00,
"availability_status": "available",
"min_time": 1,
"max_time": 30,
"insurance_required": true,
"delivery_available": true,
"status": "published"
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0e4",
"name": "Proyector Full HD 3000 lúmenes",
"rental_price": 18000.00,
"time_unit": "day",
"availability_status": "available",
"status": "published"
}
}Categorías
Las categorías organizan tu catálogo de forma jerárquica. Cada categoría puede tener una categoría padre, slug para URLs, metadatos SEO y opciones de visualización en el menú.
Endpoint base: /api/v1/categories
Scopes: categories:read, categories:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 100. |
description | string | No | Descripción de la categoría. |
parent_id | string | null | No | ID de la categoría padre (para jerarquías). |
slug | string | No | Identificador para URLs. |
icon | string | No | Icono de la categoría. |
image | string | No | Imagen de la categoría. |
status | string | No | enum: active, inactive. |
sort_order | integer | No | Orden de visualización. minimum 0. |
meta_title | string | No | Título SEO. |
meta_description | string | No | Descripción SEO. |
meta_keywords | array<string> | No | Palabras clave SEO. |
is_featured | boolean | No | Indica si la categoría es destacada. |
show_in_menu | boolean | No | Indica si se muestra en el menú. |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/categories/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/categories/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/categories/ | Crear un recurso |
PUT | /api/v1/categories/{id}/ | Actualizar un recurso |
DELETE | /api/v1/categories/{id}/ | Eliminar un recurso |
POST | /api/v1/categories/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/categories/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/categories/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/categories/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Indumentaria",
"description": "Ropa y accesorios.",
"parent_id": null,
"slug": "indumentaria",
"status": "active",
"sort_order": 1,
"is_featured": true,
"show_in_menu": true
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0d1",
"name": "Indumentaria",
"slug": "indumentaria",
"parent_id": null,
"status": "active",
"sort_order": 1
}
}Variantes y opciones
Las opciones globales definen atributos reutilizables —talle, color, addons, etc.— que se aplican a los productos para generar sus variantes. Cada opción tiene un tipo y una lista de valores posibles, y puede afectar el precio o el stock.
Endpoint base: /api/v1/products/options
Scopes: product_options:read, product_options:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 100. |
option_type | string | Sí | enum: text, number, select, multi_select, boolean, date, color, size, addon. |
display_name | string | No | Nombre visible. maxLength 200. |
values | array<object> | No | Valores posibles. Cada valor con value (requerido), display_name, image_id, color_hex, display_order, is_active, metadata. |
description | string | No | Descripción de la opción. maxLength 500. |
is_required | boolean | No | Indica si la opción es obligatoria. |
affects_price | boolean | No | Indica si la opción modifica el precio. |
affects_stock | boolean | No | Indica si la opción afecta el stock. |
display_order | integer | No | Orden de visualización. minimum 0. |
validation_rules | object | No | Reglas de validación de los valores. |
metadata | object | No | Metadatos adicionales. |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/products/options/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/products/options/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/products/options/ | Crear un recurso |
PUT | /api/v1/products/options/{id}/ | Actualizar un recurso |
DELETE | /api/v1/products/options/{id}/ | Eliminar un recurso |
POST | /api/v1/products/options/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/products/options/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/products/options/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/products/options/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Talle",
"option_type": "select",
"display_name": "Talle de la prenda",
"is_required": true,
"affects_stock": true,
"values": [
{ "value": "S", "display_name": "Small", "display_order": 1 },
{ "value": "M", "display_name": "Medium", "display_order": 2 },
{ "value": "L", "display_name": "Large", "display_order": 3 }
]
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0e5",
"name": "Talle",
"option_type": "select",
"is_required": true,
"values": [
{ "value": "S", "display_name": "Small", "display_order": 1 },
{ "value": "M", "display_name": "Medium", "display_order": 2 },
{ "value": "L", "display_name": "Large", "display_order": 3 }
]
}
}Perfiles de precio
Los perfiles de precio definen cómo se calcula el precio final de un producto a partir de su costo: impuestos aplicados, margen de ganancia y modo de cálculo (directo o inverso). Pueden marcarse como perfil por defecto.
Endpoint base: /api/v1/products/pricing-profiles
Scopes: pricing_profiles:read, pricing_profiles:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 100. |
applied_taxes | array<object> | No | Impuestos aplicados al perfil. maxItems 20. |
profit | object | No | Ganancia: type (enum percentage, fixed) y value (minimum 0). |
calculation_mode | string | No | enum: forward, reverse. |
is_default | boolean | No | Indica si es el perfil por defecto. |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/products/pricing-profiles/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/products/pricing-profiles/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/products/pricing-profiles/ | Crear un recurso |
PUT | /api/v1/products/pricing-profiles/{id}/ | Actualizar un recurso |
DELETE | /api/v1/products/pricing-profiles/{id}/ | Eliminar un recurso |
POST | /api/v1/products/pricing-profiles/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/products/pricing-profiles/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/products/pricing-profiles/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/products/pricing-profiles/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Margen mayorista",
"calculation_mode": "forward",
"is_default": false,
"profit": { "type": "percentage", "value": 35 },
"applied_taxes": [
{ "name": "IVA", "rate": 21 }
]
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0e6",
"name": "Margen mayorista",
"calculation_mode": "forward",
"is_default": false,
"profit": { "type": "percentage", "value": 35 }
}
}Promociones
Las promociones aplican descuentos a productos, servicios o alquileres: porcentaje, monto fijo, "comprá X y llevá Y" o bundles. Permiten acotar la vigencia por fechas, la cantidad mínima y los usos máximos totales o por cliente.
Endpoint base: /api/v1/promotions
Scopes: promotions:read, promotions:write
Campos
| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
name | string | Sí | minLength 1, maxLength 200. |
promotion_type | string | Sí | enum: percentage, fixed_amount, buy_x_get_y, bundle. |
description | string | null | No | Descripción de la promoción. |
value | number | No | Valor del descuento. minimum 0. |
applies_to | string | No | enum: all, specific. |
entity_type | string | null | No | enum: product, service, rental. |
entity_ids | array<string> | No | IDs de las entidades alcanzadas. |
variant_ids | array<string> | No | IDs de variantes alcanzadas. |
start_date | string | null | No | Fecha de inicio. format: date-time. |
end_date | string | null | No | Fecha de fin. format: date-time. |
min_quantity | integer | No | Cantidad mínima para aplicar. minimum 1. |
max_uses | integer | null | No | Usos máximos totales. minimum 1. |
max_uses_per_customer | integer | null | No | Usos máximos por cliente. minimum 1. |
buy_quantity | integer | No | Cantidad a comprar (para buy_x_get_y). minimum 0. |
get_quantity | integer | No | Cantidad a obtener (para buy_x_get_y). minimum 0. |
get_discount_percentage | number | No | Descuento sobre la cantidad obtenida. minimum 0, maximum 100. |
bundle_entity_ids | array<string> | No | IDs de las entidades del bundle. |
bundle_discount | number | No | Descuento del bundle. minimum 0. |
status | string | No | enum: active, draft, expired, archived, deleted. |
is_active | boolean | No | Indica si la promoción está activa. |
tags | array<string> | No | Etiquetas. |
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET | /api/v1/promotions/list/ | Listar recursos (con filtros y paginación) |
GET | /api/v1/promotions/{id}/ | Obtener un recurso por su ID |
POST | /api/v1/promotions/ | Crear un recurso |
PUT | /api/v1/promotions/{id}/ | Actualizar un recurso |
DELETE | /api/v1/promotions/{id}/ | Eliminar un recurso |
POST | /api/v1/promotions/bulk/create/ | Crear varios recursos en lote |
PUT | /api/v1/promotions/bulk/update/ | Actualizar varios recursos en lote |
POST | /api/v1/promotions/bulk/delete/ | Eliminar varios recursos en lote |
Petición
POST /api/v1/promotions/
Content-Type: application/json
X-API-Key: TU_TOKEN
{
"name": "Descuento de verano",
"promotion_type": "percentage",
"value": 15,
"applies_to": "specific",
"entity_type": "product",
"entity_ids": ["66f1a2b3c4d5e6f7a8b9c0e2"],
"start_date": "2026-06-01T00:00:00Z",
"end_date": "2026-06-30T23:59:59Z",
"min_quantity": 1,
"status": "active",
"is_active": true
}Respuesta
{
"success": true,
"data": {
"_id": "66f1a2b3c4d5e6f7a8b9c0e7",
"name": "Descuento de verano",
"promotion_type": "percentage",
"value": 15,
"applies_to": "specific",
"entity_type": "product",
"status": "active",
"is_active": true
}
}