API

Documentación para desarrolladores

Recursos: Catálogo

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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 200.
base_pricenumberPrecio base. minimum 0, maximum 999999999999.99.
descriptionstringNoDescripción del producto.
skustringNoCódigo interno (SKU).
barcodestringNoCódigo de barras.
category_idstringNoID de la categoría a la que pertenece.
costnumberNoCosto del producto. minimum 0, maximum 999999999999.99.
track_stockbooleanNoIndica si se controla el stock.
stockintegerNoStock disponible. minimum 0, maximum 999999999.
total_stockintegerNoStock total. minimum 0, maximum 999999999.
min_stockintegerNoStock mínimo de alerta. minimum 0, maximum 999999999.
unitstringNoUnidad de medida.
statusstringNoenum: draft, published, paused, deleted, archived.
imagesarray<string>NoIDs o URLs de imágenes.
attributesobjectNoAtributos personalizados.
variantsarray | objectNoVariantes del producto.
has_variantsbooleanNoIndica si el producto tiene variantes.
global_option_refsarrayNoReferencias a opciones globales.
tagsarray<string>NoEtiquetas.
seoobjectNoMetadatos SEO.
shippingobjectNoConfiguración de envío.
tax_ratenumberNoAlícuota de impuesto. minimum 0, maximum 100.
weightnumberNoPeso. minimum 0, maximum 999999999.
dimensionsobjectNoDimensiones físicas.
featuredbooleanNoIndica si el producto es destacado.
price_historyarrayNoHistorial de precios.
quantity_price_tiersarray<object>NoTramos de precio por cantidad (min_quantity requerido en cada tramo).
promotionsarray<object>NoPromociones embebidas (name y promotion_type requeridos en cada una).
pricing_compositionobjectNoComposición de precio (costo de proveedor, impuestos aplicados, ganancia).

Endpoints

MétodoEndpointDescripció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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 200.
descriptionstringNoDescripción del servicio.
category_idstringNoID de la categoría a la que pertenece.
pricenumberNoPrecio del servicio. minimum 0.
base_pricenumberNoPrecio base. minimum 0.
pricing_typestringNoenum: fixed, hourly, project, custom.
durationintegerNoDuración del servicio.
duration_unitstringNoenum: minutes, hours, days, weeks.
availabilityobjectNoConfiguración de disponibilidad.
location_typestringNoenum: on_site, remote, hybrid.
service_areaarray<string>NoZonas donde se presta el servicio.
imagesarray<string>NoIDs o URLs de imágenes.
requirementsarray<string>NoRequisitos previos.
included_itemsarray<string>NoÍtems incluidos.
excluded_itemsarray<string>NoÍtems no incluidos.
tagsarray<string>NoEtiquetas.
statusstringNoenum: draft, published, paused, deleted, archived.
booking_requiredbooleanNoIndica si requiere reserva previa.
advance_booking_daysintegerNoDías de anticipación para reservar. minimum 0.

Endpoints

MétodoEndpointDescripció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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 200.
descriptionstringNoDescripción del alquiler.
category_idstringNoID de la categoría a la que pertenece.
rental_pricenumberNoPrecio del alquiler. minimum 0, maximum 999999999999.99.
base_pricenumberNoPrecio base. minimum 0, maximum 999999999999.99.
time_unitstringNoenum: hour, day, week, month.
security_depositnumberNoDepósito de garantía. minimum 0, maximum 999999999999.99.
availability_statusstringNoenum: available, in_use, maintenance, unavailable.
locationstringNoUbicación del bien en alquiler.
imagesarray<string>NoIDs o URLs de imágenes.
terms_conditionsstringNoTérminos y condiciones del alquiler.
min_timeintegerNoTiempo mínimo de alquiler. minimum 1.
max_timeintegerNoTiempo máximo de alquiler.
tagsarray<string>NoEtiquetas.
featuresarray<string>NoCaracterísticas del bien.
insurance_requiredbooleanNoIndica si se requiere seguro.
delivery_availablebooleanNoIndica si hay entrega a domicilio.
statusstringNoenum: draft, published, paused, deleted, archived.

Endpoints

MétodoEndpointDescripció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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 100.
descriptionstringNoDescripción de la categoría.
parent_idstring | nullNoID de la categoría padre (para jerarquías).
slugstringNoIdentificador para URLs.
iconstringNoIcono de la categoría.
imagestringNoImagen de la categoría.
statusstringNoenum: active, inactive.
sort_orderintegerNoOrden de visualización. minimum 0.
meta_titlestringNoTítulo SEO.
meta_descriptionstringNoDescripción SEO.
meta_keywordsarray<string>NoPalabras clave SEO.
is_featuredbooleanNoIndica si la categoría es destacada.
show_in_menubooleanNoIndica si se muestra en el menú.

Endpoints

MétodoEndpointDescripció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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 100.
option_typestringenum: text, number, select, multi_select, boolean, date, color, size, addon.
display_namestringNoNombre visible. maxLength 200.
valuesarray<object>NoValores posibles. Cada valor con value (requerido), display_name, image_id, color_hex, display_order, is_active, metadata.
descriptionstringNoDescripción de la opción. maxLength 500.
is_requiredbooleanNoIndica si la opción es obligatoria.
affects_pricebooleanNoIndica si la opción modifica el precio.
affects_stockbooleanNoIndica si la opción afecta el stock.
display_orderintegerNoOrden de visualización. minimum 0.
validation_rulesobjectNoReglas de validación de los valores.
metadataobjectNoMetadatos adicionales.

Endpoints

MétodoEndpointDescripció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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 100.
applied_taxesarray<object>NoImpuestos aplicados al perfil. maxItems 20.
profitobjectNoGanancia: type (enum percentage, fixed) y value (minimum 0).
calculation_modestringNoenum: forward, reverse.
is_defaultbooleanNoIndica si es el perfil por defecto.

Endpoints

MétodoEndpointDescripció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

CampoTipoRequeridoNotas
namestringminLength 1, maxLength 200.
promotion_typestringenum: percentage, fixed_amount, buy_x_get_y, bundle.
descriptionstring | nullNoDescripción de la promoción.
valuenumberNoValor del descuento. minimum 0.
applies_tostringNoenum: all, specific.
entity_typestring | nullNoenum: product, service, rental.
entity_idsarray<string>NoIDs de las entidades alcanzadas.
variant_idsarray<string>NoIDs de variantes alcanzadas.
start_datestring | nullNoFecha de inicio. format: date-time.
end_datestring | nullNoFecha de fin. format: date-time.
min_quantityintegerNoCantidad mínima para aplicar. minimum 1.
max_usesinteger | nullNoUsos máximos totales. minimum 1.
max_uses_per_customerinteger | nullNoUsos máximos por cliente. minimum 1.
buy_quantityintegerNoCantidad a comprar (para buy_x_get_y). minimum 0.
get_quantityintegerNoCantidad a obtener (para buy_x_get_y). minimum 0.
get_discount_percentagenumberNoDescuento sobre la cantidad obtenida. minimum 0, maximum 100.
bundle_entity_idsarray<string>NoIDs de las entidades del bundle.
bundle_discountnumberNoDescuento del bundle. minimum 0.
statusstringNoenum: active, draft, expired, archived, deleted.
is_activebooleanNoIndica si la promoción está activa.
tagsarray<string>NoEtiquetas.

Endpoints

MétodoEndpointDescripció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
  }
}