Guía técnica paso a paso para la integración con el ambiente sandbox de interoperabilidad del Ministerio de Salud de Colombia con mTLS y validación de RIPS JSON y FHIR
Salud Digital

Guía Práctica de Integración con el Sandbox de MinSalud: Certificados mTLS, Validación RIPS JSON y Pruebas FHIR R4

Guía paso a paso para desarrolladores e IPS en Colombia: Cómo conectarse con éxito al ambiente de pruebas (Sandbox) de MinSalud, configurar certificados mTLS y superar la malla validadora de RIPS JSON.

La entrada en vigencia obligatoria de la Resolución 2275 de 2023 y los decretos reglamentarios de la Ley 2015 de 2020 en Colombia han transformado drásticamente la relación técnica entre las Instituciones Prestadoras de Salud (IPS), los proveedores de software médico y el Ministerio de Salud y Protección Social (MinSalud). Los antiguos archivos planos (.TXT) del Registro Individual de Prestación de Servicios de Salud (RIPS) han sido reemplazados por paquetes transaccionales JSON articulados electrónicamente con la DIAN y perfiles semánticos HL7 FHIR R4.

Para que una clínica o plataforma Healthtech pueda transmitir atenciones médicas a los servicios oficiales de producción, MinSalud exige superar una batería de pruebas de conformidad en su Ambiente de Pruebas (Sandbox de Interoperabilidad).

Sin embargo, el proceso de integración suele convertirse en un dolor de cabeza para los equipos de ingeniería debido a la rigidez de los controles de seguridad: autenticación mutua por certificados digitales (mTLS), tokenización OAuth 2.0 y mallas validadoras con más de 200 reglas de consistencia clínica que rechazan peticiones enteras ante el menor descuido tipográfico.

En este artículo técnico paso a paso, explicaremos cómo preparar tu infraestructura para interactuar con el Sandbox de MinSalud, cómo configurar los certificados criptográficos en Node.js, cómo estructurar y firmar los payloads JSON y cómo interpretar los códigos de error devueltos por la plataforma validadora.


1. Requisitos Previos y Topología de Conexión con MinSalud

El ambiente de interoperabilidad de MinSalud no es una API pública accesible con una simple API Key. Por tratarse de datos sensibles de salud ciudadana protegidos por la Ley 1581 de 2012, el acceso requiere una arquitectura de Confianza Cero (Zero Trust):

┌────────────────────────────────────────────────────────────────────────┐
│               Flujo de Seguridad con el Sandbox MinSalud               │
└────────────────────────────────────────────────────────────────────────┘

 [Servidor IPS / Healthtech]

         ├───► 1. Handshake Criptográfico Bidireccional (mTLS)
         │     Presenta Certificado Digital (.CRT / .KEY de Certicámara/GSE)

 [Firewall / API Gateway MinSalud]

         ├───► 2. Validación de Certificado y Código de Habilitación REPS

 [Servidor de Identidad OAuth 2.0]

         ├───► 3. Emite Access Token JWT con vigencia de 3600 segundos

 [Malla Validadora RIPS JSON / Motor FHIR R4]

         ├───► 4. Valida consistencia cruzada (CUPS vs CIE-10 vs Sexo vs Edad)

 [Respuesta Operativa]
         ├───► HTTP 200 OK: Código Único de Validación (CUV generado)
         └───► HTTP 400 / 422: OperationOutcome estructurado con glosas

Componentes de Configuración Obligatorios

  1. Código de Habilitación en el REPS: Tu institución debe contar con un código válido de 12 dígitos en el Registro Especial de Prestadores de Servicios de Salud (REPS) registrado en el portal SISPRO.
  2. Certificado Digital Abierto Clase II o III: Emitido por una entidad de certificación digital acreditada por la ONAC en Colombia (Certicámara, GSE o Andes SCD). El certificado debe ser de persona jurídica e incluir el NIT del prestador.
  3. Cuenta Activa en el Mecanismo de Transferencia Único: Credenciales asignadas para el ambiente de pruebas (sandbox.sispro.gov.co o endpoint designado por MinSalud).

2. Configuración de Certificados Digitales y Mutual TLS (mTLS)

En una conexión TLS estándar (HTTPS común), solo el cliente valida la identidad del servidor. En mTLS, el servidor de MinSalud también exige que tu servidor demuestre criptográficamente su identidad antes de permitir cualquier intercambio de bytes.

Extracción de Claves desde el Contenedor .pfx o .p12

Las entidades certificadoras suelen entregar un archivo en formato PKCS#12 (.pfx). Debemos extraer la clave privada (.key) y el certificado público (.crt) mediante OpenSSL:

# 1. Extraer la clave privada sin cifrado para el backend
openssl pkcs12 -in certificado_prestador.pfx -nocerts -out client_private.key -nodes

# 2. Extraer el certificado público del prestador
openssl pkcs12 -in certificado_prestador.pfx -clcerts -nokeys -out client_certificate.crt

# 3. Extraer la cadena de la autoridad certificadora (CA Bundle)
openssl pkcs12 -in certificado_prestador.pfx -cacerts -nokeys -out ca_chain.crt

3. Implementación en Node.js y TypeScript: Cliente Seguro mTLS

A continuación desarrollamos un cliente HTTP en TypeScript utilizando el módulo nativo https de Node.js y axios para gestionar el canal mTLS y autenticarse contra el servicio de MinSalud:

import fs from 'fs';
import path from 'path';
import https from 'https';
import axios, { AxiosInstance } from 'axios';

export interface MinSaludAuthResponse {
  access_token: string;
  token_type: string;
  expires_in: number;
}

export class MinSaludSandboxClient {
  private httpClient: AxiosInstance;
  private token: string | null = null;
  private tokenExpiresAt: number = 0;

  constructor() {
    // 1. Cargar certificados digitales
    const certPath = process.env.MINSALUD_CERT_PATH || path.join(__dirname, '../certs/client_certificate.crt');
    const keyPath = process.env.MINSALUD_KEY_PATH || path.join(__dirname, '../certs/client_private.key');
    const caPath = process.env.MINSALUD_CA_PATH || path.join(__dirname, '../certs/ca_chain.crt');

    const httpsAgent = new https.Agent({
      cert: fs.readFileSync(certPath),
      key: fs.readFileSync(keyPath),
      ca: fs.existsSync(caPath) ? fs.readFileSync(caPath) : undefined,
      rejectUnauthorized: true, // Validar estrictamente la cadena de certificados
      keepAlive: true,
    });

    // 2. Instancia de Axios vinculada al agente mTLS
    this.httpClient = axios.create({
      baseURL: process.env.MINSALUD_SANDBOX_BASE_URL || 'https://sandbox.minsalud.gov.co/api/v1',
      httpsAgent,
      timeout: 30000, // 30 segundos de timeout
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });
  }

  /**
   * Obtiene o renueva el token OAuth2 mediante credenciales de cliente
   */
  public async getAccessToken(): Promise<string> {
    const now = Date.now();
    if (this.token && this.tokenExpiresAt > now + 60000) {
      return this.token;
    }

    try {
      const response = await this.httpClient.post<MinSaludAuthResponse>('/auth/token', {
        grant_type: 'client_credentials',
        client_id: process.env.MINSALUD_CLIENT_ID,
        client_secret: process.env.MINSALUD_CLIENT_SECRET,
        reps_code: process.env.MINSALUD_REPS_CODE, // Código de 12 dígitos de la IPS
      });

      this.token = response.data.access_token;
      this.tokenExpiresAt = now + response.data.expires_in * 1000;
      console.log('[MinSalud Client] Token OAuth2 obtenido con éxito vía canal mTLS');
      return this.token;
    } catch (error: any) {
      console.error('[MinSalud Auth Error]', error.response?.data || error.message);
      throw new Error('Fallo crítico en la autenticación mTLS con MinSalud Sandbox');
    }
  }

  /**
   * Envía un paquete transaccional de RIPS JSON para validación
   */
  public async submitRipsPackage(ripsPayload: Record<string, any>): Promise<any> {
    const token = await this.getAccessToken();

    try {
      const response = await this.httpClient.post('/rips/validador/validar', ripsPayload, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      return response.data;
    } catch (error: any) {
      // Capturar respuesta estructurada de la malla validadora
      if (error.response?.data) {
        return error.response.data;
      }
      throw error;
    }
  }
}

4. Estructura del Payload RIPS JSON (Resolución 2275 de 2023)

A diferencia del archivo plano delimitado por comas, el formato de la Resolución 2275 exige un documento JSON fuertemente anidado con los datos de la factura, el prestador y las listas de atenciones:

{
  "numDocumentoIdObligado": "901234567",
  "numFactura": "FEV-1029",
  "tipoNota": null,
  "numNota": null,
  "usuarios": [
    {
      "tipoDocumentoIdentificacion": "CC",
      "numDocumentoIdentificacion": "1020304050",
      "tipoUsuario": "01",
      "fechaNacimiento": "1990-06-15",
      "codSexo": "M",
      "codPaisResidencia": "170",
      "codMunicipioResidencia": "11001",
      "codZonaTerritorialResidencia": "01",
      "incapacidad": "NO",
      "codPaisOrigen": "170",
      "servicios": {
        "consultas": [
          {
            "codPrestador": "110010000001",
            "fechaInicioAtencion": "2026-09-10 08:30",
            "numAutorizacion": null,
            "codConsulta": "890201",
            "modalidadGrupoServicioTecSal": "01",
            "grupoServicios": "01",
            "codServicio": 301,
            "finalidadTecnologiaSalud": "10",
            "causaMotivoAtencion": "38",
            "codDiagnosticoPrincipal": "K297",
            "codDiagnosticoRelacionado1": null,
            "codDiagnosticoRelacionado2": null,
            "codDiagnosticoRelacionado3": null,
            "tipoDiagnosticoPrincipal": "01",
            "tipoDocumentoIdentificacion": "CC",
            "numDocumentoIdentificacion": "79888999",
            "vrServicio": 85000.00,
            "conceptoRecaudo": "05",
            "valorPagoModerador": 0.00,
            "numFEVPagoModerador": null,
            "consecutivo": 1
          }
        ],
        "procedimientos": [],
        "urgencias": [],
        "hospitalizacion": [],
        "recienNacidos": [],
        "medicamentos": [],
        "otrosServicios": []
      }
    }
  ]
}

5. La Malla Validadora: Catálogo de Errores Comunes y Soluciones

El motor del Sandbox de MinSalud aplica mallas de consistencia clínica extremadamente estrictas. La siguiente tabla resume las fallas más habituales que impiden la obtención del CUV (Código Único de Validación):

Código de ErrorCausa del Rechazo ClínicoSolución de Ingeniería
VAL-ERR-042El código CUPS del procedimiento no aplica para el sexo biológico del paciente (ej. legrado uterino en paciente masculino).Validar en el frontend las reglas de género del catálogo CUPS oficial antes del despacho.
VAL-ERR-089La fecha de atención es posterior a la fecha de emisión de la Factura Electrónica de Venta (FEV).Asegurar sincronización de relojes NTP y validar que fechaInicioAtencion <= fechaFactura.
VAL-ERR-115El diagnóstico CIE-10 principal no existe en el catálogo maestro oficial o está deshabilitado como diagnóstico primario.Consumir la API de terminologías de MinSalud o la tabla oficial actualizada de CIE-10.
VAL-ERR-204El Código Único de Medicamentos (CUM) no coincide con el expediente INVIMA vigente.Verificar el formato [expediente]-[consecutivo] del catálogo INVIMA de medicamentos regulados.

6. Generación del CUV y Articulación con la DIAN

Cuando el payload supera satisfactoriamente todas las reglas de la malla validadora, el Sandbox responde con código HTTP 200 OK y emite el Código Único de Validación (CUV):

{
  "estado": "VALIDADO",
  "cuv": "c8f92bdc1e34a7891234567890abcdef1234567890abcdef1234567890abcdef",
  "fechaValidacion": "2026-09-10T14:15:30-05:00",
  "numFactura": "FEV-1029",
  "totalRegistros": 1,
  "inconsistencias": []
}

💡 Regla de Negocio Crítica: El CUV emitido por MinSalud debe incrustarse de forma obligatoria dentro del XML de la Factura Electrónica de Salud (sector salud) remitida a la DIAN. Si la factura se envía a la DIAN sin el CUV o con un CUV rechazado por MinSalud, la DIAN no reconocerá el documento y la EPS o entidad aseguradora glosará el 100% del cobro.


7. Consultoría Especializada en Interoperabilidad MinSalud con DoneAPI

El proceso de homologación ante el Sandbox de MinSalud no tiene por qué retrasar la operación comercial ni la facturación de tu clínica o empresa tecnológica.

En DoneAPI ayudamos a IPS, EPS, redes de laboratorios clínicos y empresas de software médico (Healthtech) en toda Colombia a:

  • Configuración Llave en Mano de Conectividad mTLS: Gestión de certificados digitales, llaves privadas y túneles seguros con los servidores ministeriales.
  • Microservicio Validador Pre-MinSalud: Implementa nuestro motor local que audita tus datos contra la malla oficial antes de enviarlos a MinSalud, reduciendo los rechazos a cero.
  • Mapeo Automático de EMR Legacy a RIPS JSON: Transformación de bases de datos relacionales existentes a los formatos estructurados de la Resolución 2275.
  • Acompañamiento en Pruebas de Habilitación Oficial: Soporte técnico continuo hasta la obtención de la certificación definitiva en producción.

💬 ¿Tu clínica o empresa de software de salud necesita habilitar su conexión al Sandbox de MinSalud o certificar el envío de RIPS JSON sin fricciones?
Chatea directamente con nuestros ingenieros especializados en salud digital a través de WhatsApp.

Conéctate al Sandbox de MinSalud y Aprueba tus RIPS JSON con DoneAPI

Supera la malla validadora, automatiza tus certificados mTLS y genera el CUV en segundos sin traumatismos técnicos.

Hablar con un Consultor de Salud Digital por WhatsApp

8. Conclusión

Superar las pruebas en el Sandbox de MinSalud no es un obstáculo insalvable si se cuenta con la arquitectura de seguridad adecuada y una comprensión profunda de las reglas de negocio de la Resolución 2275 de 2023.

Al implementar un cliente seguro con certificados mTLS, renovación automática de tokens OAuth 2.0 y validaciones clínicas preventivas, tu institución médica se asegura una transición fluida hacia el ecosistema nacional de salud digital, garantizando la continuidad de los pagos de facturación y el estricto apego a la ley colombiana.

Herramientas de Inteligencia Artificial para emprendedores

Desbloquea tu arsenal de automatización.

Regístrate gratis y accede a plantillas para n8n y Make.com, packs de prompts probados para IA, y guías exclusivas diseñadas para escalar tu negocio digital.

Crear cuenta y obtén recursos gratis