Integraciones API REST y MCP
Descripción general y autenticación de la API REST
Conecte con la API REST actual de ExCoil: acceso, rutas reales, cuerpos JSON, unidades, respuestas y límites operativos.
Revisado el
1. Acceso y separación entre REST y MCP
REST requiere una suscripción Enterprise o Manufacturer con estado active o trialing. El servidor comprueba la suscripción actual del propietario en cada petición; conservar una clave antigua no mantiene el acceso tras una reducción de plan o la pérdida del estado válido.
REST usa /api/v1 y claves que empiezan por exk_. MCP es una interfaz Streamable HTTP separada en /api/mcp, exclusiva de Manufacturer, con tokens Bearer propios configurados manualmente. Una credencial no sustituye a la otra. Estas rutas REST no implementan un flujo de autorización OAuth.
Las rutas siguientes exponen seis motores de serpentines aleteados y la lista de refrigerantes. No ofrecen CRUD de proyectos por REST, Shell & Tube, archivos de fabricación ni exportación CAD/PDF. El permiso projects:read de una clave REST no crea un endpoint de proyectos. Los detalles de fabricación siguen siendo exclusivos de Manufacturer; esta guía no los habilita mediante REST.
2. URL base y autenticación
Use el origen del entorno ExCoil donde la API esté realmente desplegada, seguido de /api/v1. Para producción, la URL base es https://excoil.net/api/v1. Una vista previa es otro entorno; el código de una vista previa no demuestra su publicación en producción.
Genere una clave en la página Claves API y guarde su valor completo inmediatamente: se muestra una sola vez. Envíe Authorization: Bearer seguido de la clave REST en todas las peticiones, incluidos GET /health y GET /refrigerants. Respete la mayúscula de Bearer y el espacio. La cookie de sesión del navegador no autentica estas rutas.
Envíe Content-Type: application/json en los POST de cálculo. Guarde las claves en almacenamiento seguro del servidor, nunca en paquetes del navegador, URLs, prompts, repositorios o registros compartidos. Si pierde o expone una clave, revóquela y sustitúyala; las claves antiguas se pueden gestionar incluso tras reducir el plan.
bash
BASE_URL='https://excoil.net/api/v1'
EXCOIL_API_KEY='exk_SUSTITUYA_POR_SU_CLAVE_REST'
curl --include "$BASE_URL/health" \
-H "Authorization: Bearer $EXCOIL_API_KEY"3. Rutas implementadas
Todos los caminos son relativos a /api/v1 y requieren autenticación y suscripción válida. Los POST de cálculo y /refrigerants también exigen calc:read. /health no añade esa comprobación de permiso.
| Método | Ruta | Finalidad |
|---|---|---|
| GET | /health | Estado, versión y fecha/hora de la API |
| GET | /refrigerants | Identificadores de refrigerantes disponibles |
| POST | /calculate/chilled-water | Serpentín de agua fría |
| POST | /calculate/hot-water | Serpentín de agua caliente |
| POST | /calculate/steam-coil | Serpentín de vapor |
| POST | /calculate/dry-cooler | Dry cooler |
| POST | /calculate/dx-evaporator | Evaporador DX |
| POST | /calculate/dx-evaporator/balanced | Evaporador DX con solver de balance |
| POST | /calculate/dx-condenser | Condensador DX |
| POST | /calculate/dx-condenser/balanced | Condensador DX con solver de balance |
4. Construya el cuerpo JSON correcto
Las rutas ordinarias reciben directamente el objeto de entrada del motor, sin envoltorio data ni inputs. Agua fría y caliente usan air, water, coil, hydraulic y calib; vapor usa air, steam, coil, hydraulic y calib; dry cooler tiene sus propios campos fluid, air, coil, hydraulic y calib. DX usa air, coil, ref y calib. Los campos obligatorios varían; no copie el objeto de presentación del formulario ni reutilice el cuerpo de otro módulo.
La ruta balanceada del evaporador DX es la excepción: envíe un objeto con inputs y, opcionalmente, options. inputs contiene la entrada completa del motor del evaporador DX. La ruta balanceada del condensador DX recibe la entrada del condensador directamente, sin el envoltorio inputs/options del evaporador.
Para DX, use ref.fluid con un identificador exacto de /refrigerants. El enrutador también reconoce los campos heredados ref.refrigerant o refrigerant en la raíz al elegir la tabla, pero el campo canónico del motor sigue siendo ref.fluid. Encontrar la tabla no sustituye los demás campos obligatorios de ref.
La capa REST realiza comprobaciones limitadas del cuerpo y refrigerante, no una validación exhaustiva del esquema. No convierte automáticamente las unidades de la interfaz ni completa todos los campos ausentes. Valide valores obligatorios, rangos físicos, geometría y calibración antes del envío.
5. Las unidades forman parte del contrato
La API usa los campos y unidades del motor, independientemente de las unidades de visualización de la aplicación. Los números JSON deben estar convertidos; no envíe cadenas numéricas localizadas ni etiquetas de unidad en campos numéricos.
| Campo o sufijo | Significado y unidad |
|---|---|
| Vdot_m3_s; mdot_kg_s | Caudal volumétrico en m³/s; másico en kg/s |
| T_in_C; Tevap_C; *_K | Temperatura en °C; diferencias o sobrecalentamiento en K |
| height_m; width_m; Do_m; wall_m | Geometría en metros, no milímetros |
| P_Pa; *_Pa; *_kPa | Presión en Pa o kPa según el nombre |
| RH_in; freeAreaRatio | Fracciones de 0 a 1, no porcentajes |
| glycol_pct | Porcentaje de glicol de serpentines de agua, no fracción de 0 a 1 |
| fpi | Aletas por pulgada, no por metro |
| P_steam_kPa | Presión de vapor en kPa manométricos, no Pa absolutos |
| Q_total_W; h_out | Capacidad en W; entalpía de salida de agua fría/evaporador DX en J/kg de aire seco |
6. Lea la respuesta y los diagnósticos
Un cálculo exitoso usa {"success":true,"data":...}, donde data es el resultado del motor. GET /refrigerants usa ese envoltorio con una lista de identificadores. GET /health es distinto: devuelve status, version y timestamp directamente, sin success ni data.
HTTP 200 y success:true indican que el solver devolvió un resultado, no que se cumplieron todos los criterios de ingeniería. Revise flags, convergencia, notes y los diagnósticos de rendimiento disponibles. Conserve los avisos junto con las entradas y el resultado; no elimine una indicación de falta de convergencia o viabilidad.
Los endpoints balanceados devuelven su propio resultado dentro de data. Consulte el contrato concreto, sin suponer rutas perf o flags idénticas en todos los endpoints. Un error de balance energético bajo es un diagnóstico numérico, no validación independiente, certificación ni autorización de fabricación.
json
{
"status": "ok",
"version": "1.0.0",
"timestamp": "<fecha/hora ISO-8601>"
}7. Límites de peticiones y reintentos
El limitador actúa por clave REST y proceso del servidor. Usa rateLimit de la clave, con un valor de respaldo de 100 peticiones por minuto si falta o es cero. La ventana de 60 segundos empieza con la primera petición admitida; no suponga que se reinicia al inicio de cada minuto del reloj.
Tras autenticar y verificar el plan, la petición admitida consume el límite antes de comprobar el permiso de la ruta o calcular. Las consultas de estado y refrigerantes, los fallos de permiso y los errores de cálculo también pueden consumirlo. Los fallos de autenticación y plan se producen antes del limitador.
Lea X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset. Reset es una marca Unix en segundos, no milisegundos ni una duración. El 429 incluye estos encabezados y rate_limit_exceeded; este middleware no establece Retry-After. Espere al reinicio, contemple diferencias de reloj y limite los reintentos, sin bucles continuos.
El limitador reside en memoria, se reinicia con el proceso y no es una cuota global compartida entre réplicas. No garantiza rendimiento, concurrencia ni tiempo de respuesta. Este enrutador no implementa un plazo máximo por petición ni un endpoint de tareas asíncronas con consulta de estado.
8. Diagnostique errores HTTP y de cálculo
Los fallos del enrutador devuelven error y message, sin success:false. Revise el estado HTTP y el código, y conserve mensajes saneados para diagnóstico. Los errores del parser, proxy o infraestructura pueden tener otro cuerpo; compruebe el tipo de contenido antes de asumir JSON.
| HTTP / error | Significado | Acción |
|---|---|---|
| 400 / bad_request | Cuerpo ordinario ausente/no objeto, refrigerante DX ausente/desconocido o inputs del evaporador balanceado ausente | Corrija la estructura y el identificador |
| 401 / unauthorized | Bearer ausente/incorrecto, prefijo erróneo o clave desconocida | Revise el encabezado y la clave REST, no el token MCP |
| 403 / forbidden | Clave revocada/caducada, plan/estado no válido o permiso ausente | Revise clave, suscripción del propietario y calc:read |
| 422 / calculation_error | Excepción en el controlador del solver | Revise mensaje, entradas, unidades y rango; no repita indefinidamente sin cambios |
| 429 / rate_limit_exceeded | La clave agotó la ventana actual en memoria | Use los encabezados y retrase el reintento |
json
{
"error": "unauthorized",
"message": "Invalid API key."
}9. Lista práctica de integración
- Confirme el entorno, la suscripción válida y una clave REST dedicada. Guárdela de forma segura y use solo el prefijo en diagnósticos rutinarios.
- Compruebe la conexión con /health autenticado y consulte /refrigerants para DX. Incluya ambas consultas en su presupuesto de peticiones.
- Elija la ruta y contrato exactos, convierta unidades explícitamente y valide los campos obligatorios. Consulte los detalles del módulo en la guía de calculadoras.
- Añada Authorization y Content-Type al POST y serialice la entrada completa. Use inputs/options solo para el evaporador DX balanceado.
- Compruebe estado, formato, encabezados y diagnósticos de ingeniería. Guarde las entradas, la versión del motor si se devuelve y todos los avisos junto al resultado.
- Corrija las causas de 400/401/403/422 en vez de reintentar a ciegas; espere en los 429. Revoque claves comprometidas y obtenga revisión de ingeniería antes de seleccionar, comprar o fabricar.
