Descripción
Los fees o márgenes son valores opcionales que puedes aplicar sobre las tarifas de energía eléctrica contratadas. Estos márgenes te permiten personalizar los precios finales aplicados a tus clientes.
✅ Características principales
- Completamente opcionales
- Se validan automáticamente contra límites configurados
- Puedes aplicar fees solo en algunos períodos
- Cada tarifa tiene sus propios límites
Tipos de Fees
1. precio_potencia
Margen sobre el precio de la potencia contratada.
- Unidades: €/kW/año
- Aplicación: Sobre cada período de potencia (p1-p6)
- Ejemplo: 25.0 €/kW/año en período P1
- Uso típico: Añadir margen sobre el coste de mantener potencia disponible
2. fee_energia
Margen sobre el precio de la energía consumida.
- Unidades: €/MWh
- Aplicación: Sobre cada período horario (p1-p6)
- Ejemplo: 0.05 €/MWh en período P1
- Uso típico: Añadir margen sobre el coste de la energía consumida
Períodos Tarifarios
Ambos tipos de fees se aplican por período:
| Período | Descripción |
|---|---|
| p1 | Período 1 (horario punta en 6 períodos) |
| p2 | Período 2 |
| p3 | Período 3 |
| p4 | Período 4 |
| p5 | Período 5 |
| p6 | Período 6 (horario valle en 6 períodos) |
🔍 Consultar Límites de Fees
Antes de enviar un contrato con fees/márgenes, debes consultar los límites permitidos para tu tarifa usando el endpoint de tarifas.
Endpoint de Consulta
Headers:
Authorization: Bearer <tu_token_jwt>
Campos de Límites en la Respuesta
Para cada tarifa, el API devuelve los límites de fees en los siguientes campos:
Límites de precio_potencia (€/kW/año)
valor_p1_min_precio_potencia → Mínimo permitido período P1 valor_p1_max_precio_potencia → Máximo permitido período P1 valor_p2_min_precio_potencia → Mínimo permitido período P2 valor_p2_max_precio_potencia → Máximo permitido período P2 ... hasta p6
Límites de fee_energia (€/MWh)
valor_p1_min_fee_energia → Mínimo permitido período P1 valor_p1_max_fee_energia → Máximo permitido período P1 valor_p2_min_fee_energia → Mínimo permitido período P2 valor_p2_max_fee_energia → Máximo permitido período P2 ... hasta p6
Ejemplo de Respuesta
{
"content": [
{
"id_tarifa_precios": 11539,
"alias_externo": "DELTA - PLAN SIN HORAS B2B",
"descripcion": "2.0TD",
"codigo_atr": "018",
"valor_p1_min_precio_potencia": "10.0",
"valor_p1_max_precio_potencia": "50.0",
"valor_p2_min_precio_potencia": "8.0",
"valor_p2_max_precio_potencia": "45.0",
"valor_p3_min_precio_potencia": "7.0",
"valor_p3_max_precio_potencia": "40.0",
"valor_p1_min_fee_energia": "0.01",
"valor_p1_max_fee_energia": "0.10",
"valor_p2_min_fee_energia": "0.01",
"valor_p2_max_fee_energia": "0.10",
"valor_p3_min_fee_energia": "0.01",
"valor_p3_max_fee_energia": "0.09",
"activa": true
}
],
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
Interpretación de Límites
Para la tarifa del ejemplo anterior (ID 11539):
| Concepto | Período | Mínimo | Máximo | Unidades |
|---|---|---|---|---|
| precio_potencia | P1 | 10.0 | 50.0 | €/kW/año |
| precio_potencia | P2 | 8.0 | 45.0 | €/kW/año |
| precio_potencia | P3 | 7.0 | 40.0 | €/kW/año |
| fee_energia | P1 | 0.01 | 0.10 | €/MWh |
| fee_energia | P2 | 0.01 | 0.10 | €/MWh |
| fee_energia | P3 | 0.01 | 0.09 | €/MWh |
Valores válidos para contratar:
- ✅
precio_potencia.p1 = 25.0(entre 10.0 y 50.0) - ✅
precio_potencia.p2 = 22.0(entre 8.0 y 45.0) - ✅
fee_energia.p1 = 0.05(entre 0.01 y 0.10) - ✅
fee_energia.p2 = 0.04(entre 0.01 y 0.10)
Valores inválidos:
- ❌
precio_potencia.p1 = 100.0(excede el máximo 50.0) - ❌
precio_potencia.p1 = 5.0(por debajo del mínimo 10.0) - ❌
fee_energia.p1 = 0.005(por debajo del mínimo 0.01) - ❌
fee_energia.p1 = 0.15(excede el máximo 0.10)
⚠️ Caso Especial: Límites en "0"
Si encuentras límites con valor "0" o "0.0":
{
"valor_p1_min_precio_potencia": "0",
"valor_p1_max_precio_potencia": "0"
}
Esto significa:
- ⚠️ No puedes aplicar fees para ese concepto/período en esa tarifa
- Omite ese concepto de tu objeto
margenes_tarifa_precios - El sistema rechazará cualquier valor diferente de 0 para ese concepto/período
Estructura del Request
Objeto margenes_tarifa_precios
El objeto margenes_tarifa_precios es opcional y se incluye dentro del request principal de contrato:
{
"margenes_tarifa_precios": {
"precio_potencia": {
"periodos_concepto": {
"p1": { "valor": 25.0 },
"p2": { "valor": 22.0 },
"p3": { "valor": 20.0 }
}
},
"fee_energia": {
"periodos_concepto": {
"p1": { "valor": 0.05 },
"p2": { "valor": 0.04 },
"p3": { "valor": 0.03 }
}
}
}
}
Aplicación Parcial de Fees
No es necesario especificar todos los períodos (p1-p6). Los períodos no especificados no tendrán fee aplicado.
Ejemplo válido - Solo P1 y P2:
{
"margenes_tarifa_precios": {
"precio_potencia": {
"periodos_concepto": {
"p1": { "valor": 25.0 },
"p2": { "valor": 22.0 }
}
}
}
}
Ejemplo válido - Solo fee_energia:
{
"margenes_tarifa_precios": {
"fee_energia": {
"periodos_concepto": {
"p1": { "valor": 0.05 }
}
}
}
}
Validación y Errores
Proceso de Validación
Cuando envías un contrato con fees, el sistema realiza una validación en dos fases:
FASE 2A: Validación de ID de Tarifa
- Verifica que el
id_tarifaexiste y está disponible para tu canal - Se ejecuta siempre, incluso sin fees
FASE 2B: Validación de Rangos de Fees
- Se ejecuta solo si incluyes
margenes_tarifa_precios - Valida que cada valor esté dentro del rango permitido por la tarifa
- Compara con los límites
valor_pX_min_*yvalor_pX_max_*
Errores Comunes
1. Fee Fuera de Rango (Superior)
Respuesta (400 Bad Request):
{
"error": "Errores en validación de rangos de fees:\n - Tarifa 11539, precio_potencia.p1: valor 100.0 excede el máximo permitido 50.0",
"field": "contrato.margenes_tarifa_precios",
"error_type": "tarifas_fees"
}
2. Fee Fuera de Rango (Inferior)
Respuesta (400 Bad Request):
{
"error": "Errores en validación de rangos de fees:\n - Tarifa 11539, fee_energia.p1: valor 0.005 está por debajo del mínimo permitido 0.01",
"field": "contrato.margenes_tarifa_precios",
"error_type": "tarifas_fees"
}
3. Múltiples Errores
Respuesta (400 Bad Request):
{
"error": "Errores en validación de rangos de fees:\n - Tarifa 11539, precio_potencia.p1: valor 100.0 excede el máximo permitido 50.0\n - Tarifa 11539, precio_potencia.p2: valor 5.0 está por debajo del mínimo permitido 8.0\n - Tarifa 11539, fee_energia.p1: valor 0.15 excede el máximo permitido 0.10",
"field": "contrato.margenes_tarifa_precios",
"error_type": "tarifas_fees"
}
Solución de Errores
- Consultar límites actualizados usando
GET /tarifas - Identificar tu tarifa en la respuesta
- Verificar los campos
valor_pX_min_*yvalor_pX_max_* - Ajustar tus valores para que estén dentro del rango
- Reintentar el envío del contrato
Ejemplos Completos
Ejemplo 1: Contrato Empresa con Fees Completos
{
"cups": "ES0026000010979933FW",
"provincia": "Madrid",
"municipio": "Madrid",
"cod_postal": "28001",
"calle": "Calle de Alcalá",
"numero_finca": "123",
"tipo_via_cnmc": "Calle",
"potencia_contratada": [4600, 4600, 4600, 4600, 4600, 4600],
"id_tarifa": 11539,
"iban": "ES9121000418450200051332",
"margenes_tarifa_precios": {
"precio_potencia": {
"periodos_concepto": {
"p1": { "valor": 25.0 },
"p2": { "valor": 22.0 },
"p3": { "valor": 20.0 }
}
},
"fee_energia": {
"periodos_concepto": {
"p1": { "valor": 0.05 },
"p2": { "valor": 0.04 },
"p3": { "valor": 0.03 }
}
}
},
"razon_social_titular": "Empresa Ejemplo SL",
"tipo_documento_titular": "NIF",
"numero_documento_titular": "B12345678",
"callback_url": "https://tu-servidor.com/webhook",
"years_vigencia": 1
}
Ejemplo 2: Contrato Sin Fees
{
"cups": "ES0021000005451399GM",
"provincia": "Barcelona",
"municipio": "Barcelona",
"cod_postal": "08001",
"potencia_contratada": [5750, 5750, 5750, 5750, 5750, 5750],
"id_tarifa": 10212,
"iban": "ES1234567890123456789012",
"razon_social_titular": "Tech Solutions SL",
"tipo_documento_titular": "NIF",
"numero_documento_titular": "B98765432",
"callback_url": "https://tu-servidor.com/webhook",
"years_vigencia": 1
}
Ejemplo de Código Python
import requests
# 1. Autenticarse
auth_response = requests.post(
"https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand",
json={"email": "tu_email@ejemplo.com", "password": "tu_password"}
)
token = auth_response.json()["token"]
# 2. Consultar tarifas
tarifas_response = requests.get(
"https://pre-webhooks.imaginaenergia.com/tarifas",
headers={"Authorization": f"Bearer {token}"}
)
tarifas = tarifas_response.json()["content"]
# 3. Buscar tu tarifa
mi_tarifa_id = 11539
mi_tarifa = next(t for t in tarifas if t["id_tarifa_precios"] == mi_tarifa_id)
# 4. Extraer límites
limites = {
"precio_potencia": {
"p1": {
"min": float(mi_tarifa["valor_p1_min_precio_potencia"]),
"max": float(mi_tarifa["valor_p1_max_precio_potencia"])
}
},
"fee_energia": {
"p1": {
"min": float(mi_tarifa["valor_p1_min_fee_energia"]),
"max": float(mi_tarifa["valor_p1_max_fee_energia"])
}
}
}
# 5. Validar que tus valores están dentro del rango
def validar_fee(concepto, periodo, valor):
limite = limites[concepto][periodo]
if limite["min"] <= valor <= limite["max"]:
print(f"✅ {concepto}.{periodo} válido: {valor}")
return True
else:
print(f"❌ {concepto}.{periodo} inválido: {valor}")
print(f" Rango permitido: {limite['min']} - {limite['max']}")
return False
# Validar tus márgenes
validar_fee("precio_potencia", "p1", 25.0)
validar_fee("fee_energia", "p1", 0.05)
# 6. Enviar contrato
contrato = {
"cups": "ES0026000010979933FW",
"id_tarifa": mi_tarifa_id,
"margenes_tarifa_precios": {
"precio_potencia": {
"periodos_concepto": {
"p1": { "valor": 25.0 }
}
},
"fee_energia": {
"periodos_concepto": {
"p1": { "valor": 0.05 }
}
}
}
# ... resto de campos
}
contrato_response = requests.post(
"https://pre-webhooks.imaginaenergia.com/contrato/empresa/c1",
headers={"Authorization": f"Bearer {token}"},
json=contrato
)
print(f"✅ Contrato enviado: {contrato_response.json()}")
Ejemplo de Código JavaScript
const axios = require('axios');
async function contratarConFees() {
// 1. Autenticarse
const authResponse = await axios.post(
'https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand',
{ email: 'tu_email@ejemplo.com', password: 'tu_password' }
);
const token = authResponse.data.token;
// 2. Consultar tarifas
const tarifasResponse = await axios.get(
'https://pre-webhooks.imaginaenergia.com/tarifas',
{ headers: { Authorization: `Bearer ${token}` } }
);
const tarifas = tarifasResponse.data.content;
// 3. Buscar tarifa
const miTarifaId = 11539;
const miTarifa = tarifas.find(t => t.id_tarifa_precios === miTarifaId);
// 4. Extraer límites
const limites = {
precio_potencia: {
p1: {
min: parseFloat(miTarifa.valor_p1_min_precio_potencia),
max: parseFloat(miTarifa.valor_p1_max_precio_potencia)
}
},
fee_energia: {
p1: {
min: parseFloat(miTarifa.valor_p1_min_fee_energia),
max: parseFloat(miTarifa.valor_p1_max_fee_energia)
}
}
};
// 5. Validar fees
const validarFee = (concepto, periodo, valor) => {
const limite = limites[concepto][periodo];
return valor >= limite.min && valor <= limite.max;
};
console.log('✅ Validación:', validarFee('precio_potencia', 'p1', 25.0));
// 6. Enviar contrato
const contrato = {
cups: 'ES0026000010979933FW',
id_tarifa: miTarifaId,
margenes_tarifa_precios: {
precio_potencia: {
periodos_concepto: {
p1: { valor: 25.0 }
}
},
fee_energia: {
periodos_concepto: {
p1: { valor: 0.05 }
}
}
}
// ... resto de campos
};
const contratoResponse = await axios.post(
'https://pre-webhooks.imaginaenergia.com/contrato/empresa/c1',
contrato,
{ headers: { Authorization: `Bearer ${token}` } }
);
console.log('✅ Contrato enviado:', contratoResponse.data);
}
contratarConFees().catch(console.error);
Preguntas Frecuentes
¿Los límites pueden cambiar?
Sí, los límites pueden ser actualizados por el administrador de tu canal en cualquier momento.
¿Qué pasa si no envío fees?
Los fees son completamente opcionales. Si no incluyes margenes_tarifa_precios en tu request, el contrato se procesará con los precios base de la tarifa seleccionada, sin márgenes adicionales.
¿Puedo aplicar fees solo en algunos períodos?
Sí, no es necesario especificar todos los períodos (p1-p6). Los períodos no especificados no tendrán fee aplicado y se usarán los precios base de la tarifa.
¿Puedo aplicar solo precio_potencia sin fee_energia?
Sí, puedes aplicar solo uno de los conceptos. Son completamente independientes.
¿Los límites son por canal o por tarifa?
Los límites son por tarifa. Cada tarifa tiene sus propios límites configurados, independientemente del canal que la utilice.
¿Los valores deben ser números o strings?
En tu request, envía los valores como números (float): {"valor": 25.0}
Los límites del API de tarifas vienen como strings, pero debes convertirlos a float para las comparaciones.
¿Hay límites de precisión decimal?
Usa hasta 2 decimales para fees de energía (€/MWh) y potencia (€/kW/año).
Soporte
Para consultas o incidencias:
- Email: serviciosistemas@imaginaenergia.com
- Incluir: El
request_idde la petición problemática - Horario: Lunes a Viernes, 9:00 - 18:00 CET
Referencias
- Consulta de Tarifas - Endpoint GET /tarifas
- Validación de Fees - Proceso de validación
- Documentación API - Índice principal