Tarifas
Crea precios EUR por cliente, resuelve la precedencia del catálogo y repricia borradores sin reescribir el histórico.
Las tarifas sobrescriben precios de venta del catálogo dentro de una empresa.
Son tenant-scoped, solo EUR y usan precios unitarios con cuatro decimales para
mantener precisión en productos medidos. Pertenecen al módulo de plan Productos,
pero usan scopes propios: price_lists:read y price_lists:write.
Ciclo de vida y endpoints
| Operación | Endpoint | Scope |
|---|---|---|
| Listar / crear | GET, POST /v1/price-lists | price_lists:read / price_lists:write |
| Opciones compactas | GET /v1/price-lists/options | price_lists:read |
| Leer / actualizar / eliminar | GET, PUT, DELETE /v1/price-lists/{priceList} | lectura / escritura |
| Listar / upsert de ítems | GET, POST /v1/price-lists/{priceList}/items | lectura / escritura |
| Eliminar un ítem | DELETE /v1/price-lists/{priceList}/items/{item} | price_lists:write |
| Resolver precio efectivo | POST /v1/price-lists/resolve | price_lists:read |
| Resolver hasta 100 selecciones | POST /v1/price-lists/resolve-many | price_lists:read |
| Reasignar un ítem retirado | POST /v1/price-lists/{priceList}/items/{item}/reassign | price_lists:write |
| Purgar definitivamente un ítem retirado | POST /v1/price-lists/{priceList}/items/{item}/purge | price_lists:write |
Una tarifa nace active; PUT alterna entre active e inactive. Las
inactivas siguen legibles para histórico, pero no se seleccionan en clientes o
documentos nuevos. No se puede borrar una tarifa asignada a clientes o
borradores. Los borrados de tarifa e ítem son irreversibles.
curl -X POST https://api.factuarea.com/v1/price-lists \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Idempotency-Key: 01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01" \
-H "Content-Type: application/json" \
-d '{"name":"Mayorista 2026"}'El nombre es único dentro de la empresa.
Añadir o reemplazar un precio
POST /v1/price-lists/{priceList}/items hace upsert. Un destino se puede
nombrar de tres formas mutuamente excluyentes:
- configuración comercial almacenada (
configuration_id); - selección normalizada (
selection_signature, 64 caracteres hexadecimales); - cruce legacy de producto + variante/presentación opcionales.
{
"product_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a20",
"configuration_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a21",
"unit_price": "79.5000",
"price_unit": "C62"
}Envía el id de un ítem para actualizar exactamente ese ítem. Reutilizar el
mismo destino con otro id se rechaza. price_unit debe ser compatible con el
destino. El listado acepta search sobre los nombres visibles de producto,
variante, presentación, configuración y valores de opción, además de
status=active|retired.
Precedencia de resolución
Para una selección nueva el resolver aplica este orden estable:
- tarifa dirigida a la configuración almacenada;
- tarifa dirigida a la firma de selección;
- tarifa legacy (variante + presentación, variante, presentación, producto, de más a menos específica);
- precio comercial final propio de la configuración;
- precio comercial propio de la presentación;
- precio propio de la variante por unidad base;
- precio del producto por unidad base.
Toda entrada de tarifa gana a cualquier precio propio del catálogo. Los ajustes de opción solo se suman si la fuente ganadora no los ha absorbido ya.
POST /v1/price-lists/resolve{
"price_list_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a02",
"product_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a20",
"configuration_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a21",
"selection_signature": "b7293f69a30c36b77f6d5ba27f2bc4f1f68e97e447ab8776bf080531d0a1dcee",
"option_value_ids": ["01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a22"]
}La respuesta identifica origen, unit_price, price_unit, unidad base y
snapshot de tarifa. También devuelve unit_semantics, source_amount,
option_adjustment_total y option_adjustments_absorbed, para detectar si los
ajustes de opción se absorbieron o se sumaron. Omitir price_list_id recorre
los precios propios del catálogo. Una fuente por unidad base se convierte una
vez con una presentación fija; una fuente por unidad comercial nunca se
convierte.
POST /v1/price-lists/resolve-many resuelve hasta 100 selecciones completas en
una petición de solo lectura y puede comparar cada resultado con
current_unit_price. Empareja por index, no por el orden de la respuesta. Un
destino inválido se atribuye a targets.<n>.
Destinos retirados
Cuando un borrado de catálogo confirmado invalida un destino, su entrada de tarifa queda retirada, no redirigida en silencio al precio del producto. Conserva importe, motivo/fecha y snapshot del destino, pero se excluye de la resolución, asignaciones y estadísticas.
Usa .../{item}/reassign para crear una entrada activa nueva dirigida a un
destino vivo; la retirada queda como histórico inmutable. .../{item}/purge
borra definitivamente ese histórico y exige confirm: true,
Idempotency-Key y confirmación irreversible en los clientes que respetan
x-irreversible. No se puede purgar una entrada activa o desconocida.
Contactos, borradores y repricing
Configura la tarifa de venta del contacto con PUT /v1/contacts/{contact}/customer-profile
y default_price_list_uuid; los documentos de venta nuevos conservan
price_list_id. Facturas, presupuestos, proformas, albaranes y plantillas
recurrentes devuelven id/nombre de tarifa y los campos resueltos de cada línea.
Cambiar la tarifa de un borrador con líneas exige reprice_strategy:
| Estrategia | Efecto |
|---|---|
existing_catalog_lines | Recalcula líneas con fuente price_list, variant o product. |
future_lines_only | Conserva todas las líneas y aplica la nueva tarifa solo a futuras selecciones. |
Los precios manuales, costes de oferta de proveedor y snapshots de packs nunca se reprician silenciosamente. Los documentos emitidos/históricos son snapshots inmutables y no cambian al editar una tarifa.
Errores y MCP
Ramifica por estos códigos, no por el mensaje: price_list_not_found,
duplicate_price_list_name, inactive_price_list, invalid_price_list_item y
price_list_in_use.
El dominio MCP Pricing tiene 13 tools equivalentes: list_price_lists,
create_price_list, get_price_list, update_price_list, delete_price_list,
get_price_list_options, list_price_list_items, upsert_price_list_item,
delete_price_list_item, resolve_catalog_price, resolve_many_catalog_prices,
reassign_retired_price_list_item y purge_retired_price_list_item. El consentimiento OAuth
expone price_lists.read y price_lists.write, por lo que las 13 tools están
disponibles tanto mediante OAuth como mediante API key, sujetas al módulo
Productos del plan.
Consulta Catálogo de productos, Importes y fechas y la Referencia de la API.
Conserva los valores resueltos de la línea
Conserva price_unit y las cantidades base y comerciales resueltas junto al snapshot del catálogo. additional_description añade detalle legible sin seleccionar otro precio. La vista previa de recurrentes expone la siguiente factura resuelta sin guardarla; consulta facturas recurrentes y el ejemplo concreto de respuesta de la operación.