Technical step-by-step blueprint for integrating with the Colombian Ministry of Health interoperability sandbox using mutual TLS (mTLS), RIPS JSON validation, and FHIR R4.
Digital Health

Practical Guide to MinSalud Sandbox Integration: mTLS Certificates, RIPS JSON & FHIR Testing

A step-by-step technical guide for developers and healthcare providers in Colombia: How to connect to the MinSalud interoperability sandbox, configure mTLS, and validate RIPS JSON payloads.

The mandatory enactment of Resolution 2275 of 2023 and statutory decrees under Law 2015 of 2020 in Colombia have transformed the digital health landscape for healthcare providers (IPS), medical software vendors, and the Ministry of Health and Social Protection (MinSalud). The legacy flat-file (.TXT) Individual Registry of Healthcare Services (RIPS) has been permanently replaced by transactional JSON bundles electronically synchronized with the tax authority (DIAN) and structured according to HL7 FHIR R4 standards.

Before any hospital, outpatient clinic, or HealthTech software can transmit production clinical billing data, MinSalud requires passing a rigorous battery of conformance tests inside its Interoperability Sandbox Environment.

However, this integration frequently creates engineering bottlenecks due to strict security requirements: Mutual TLS authentication via digital certificates (mTLS), OAuth 2.0 tokenization, and validation business engines executing more than 200 clinical consistency rules that reject entire submissions upon the slightest typographical error.

In this practical technical guide, we walk through preparing your infrastructure for the MinSalud Sandbox, configuring cryptographic certificates in Node.js and TypeScript, structuring compliant JSON payloads, and decoding validation error responses.


1. Prerequisites and Connection Topology with MinSalud

MinSalud’s interoperability environment is not a public web API secured by an API key. Because it processes citizen health records protected under Colombia’s statutory data protection regulations (Law 1581 of 2012), communication is governed by a Zero Trust perimeter:

┌────────────────────────────────────────────────────────────────────────┐
│                   MinSalud Sandbox Security Architecture               │
└────────────────────────────────────────────────────────────────────────┘

 [Healthcare Provider / HealthTech Server]

         ├───► 1. Bidirectional Cryptographic Handshake (mTLS)
         │     Presents Digital Certificate (.CRT / .KEY from Certicámara / GSE)

 [MinSalud Edge Gateway / WAF]

         ├───► 2. Validates Certificate Authority Chain & REPS 12-Digit Code

 [OAuth 2.0 Identity Server]

         ├───► 3. Issues 3600-second JWT Access Token

 [RIPS JSON Validation Engine / FHIR Gateway]

         ├───► 4. Enforces Cross-Rule Consistency (CUPS vs ICD-10 vs Sex vs Age)

 [Operational Response]
         ├───► HTTP 200 OK: Unique Validation Code (CUV Generated)
         └───► HTTP 400 / 422: Structured OperationOutcome with Audit Inconsistencies

Mandatory Technical Prerequisites

  1. REPS Accreditation Code: Your healthcare institution must hold a valid 12-digit code in the Special Registry of Healthcare Providers (REPS) registered within the SISPRO portal.
  2. Open Class II or III Digital Certificate: Issued by an ONAC-accredited certification authority in Colombia (Certicámara, GSE, or Andes SCD). The certificate must represent a legal entity and embed the provider’s NIT.
  3. Active Sandbox Credentials: Test environment credentials provisioned for sandbox.sispro.gov.co or the designated ministerial gateway endpoint.

2. Digital Certificate Configuration & Mutual TLS (mTLS)

In standard TLS (regular HTTPS), only the client verifies the server’s identity. Under mTLS, MinSalud’s gateway also requires your backend server to cryptographically prove its identity before allowing any byte exchange.

Extracting Keys from .pfx or .p12 Keystores

Certification authorities typically deliver certificates encapsulated in PKCS#12 format (.pfx). We extract the unencrypted private key (.key), public certificate (.crt), and root CA bundle using OpenSSL:

# 1. Extract unencrypted private key for the backend service
openssl pkcs12 -in provider_certificate.pfx -nocerts -out client_private.key -nodes

# 2. Extract public provider certificate
openssl pkcs12 -in provider_certificate.pfx -clcerts -nokeys -out client_certificate.crt

# 3. Extract Certificate Authority chain (CA Bundle)
openssl pkcs12 -in provider_certificate.pfx -cacerts -nokeys -out ca_chain.crt

3. Node.js & TypeScript Implementation: Enterprise mTLS Client

Below is a production-ready HTTP client in TypeScript using Node’s native https.Agent and axios to negotiate the mTLS handshake and authenticate against the MinSalud identity server:

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. Load cryptographic certificates
    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, // Strictly enforce CA chain validation
      keepAlive: true,
    });

    // 2. Instantiate Axios with the mTLS agent
    this.httpClient = axios.create({
      baseURL: process.env.MINSALUD_SANDBOX_BASE_URL || 'https://sandbox.minsalud.gov.co/api/v1',
      httpsAgent,
      timeout: 30000, // 30-second connection timeout
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });
  }

  /**
   * Acquire or refresh OAuth2 Bearer token via client credentials
   */
  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, // 12-digit REPS registration
      });

      this.token = response.data.access_token;
      this.tokenExpiresAt = now + response.data.expires_in * 1000;
      console.log('[MinSalud Client] OAuth2 token acquired successfully over mTLS tunnel');
      return this.token;
    } catch (error: any) {
      console.error('[MinSalud Auth Error]', error.response?.data || error.message);
      throw new Error('Critical failure negotiating mTLS authentication with MinSalud Sandbox');
    }
  }

  /**
   * Submit transactional RIPS JSON package for ministerial validation
   */
  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) {
      if (error.response?.data) {
        return error.response.data;
      }
      throw error;
    }
  }
}

4. Structure of Compliant RIPS JSON Payloads (Resolution 2275)

Unlike legacy CSV files, Resolution 2275 requires a nested JSON hierarchy binding medical invoices, provider registries, and structured arrays of clinical services:

{
  "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. Navigating the Validation Engine: Common Errors & Fixes

MinSalud’s validation engine executes strict consistency evaluations. The table below lists the most frequent causes of submission failure and how to resolve them:

Error CodeValidation Rejection CauseEngineering Remediation
VAL-ERR-042The procedure’s CUPS code does not align with the patient’s biological sex (e.g., uterine curettage recorded for a male patient).Validate gender compatibility rules against the official CUPS catalog prior to transmission.
VAL-ERR-089Clinical service delivery timestamp is chronologically after the Electronic Sales Invoice (FEV) issue date.Synchronize system NTP clocks and verify that fechaInicioAtencion <= fechaFactura.
VAL-ERR-115Primary ICD-10 code does not exist in the official master catalog or is prohibited as a primary diagnosis.Query MinSalud’s terminology endpoint or update the local ICD-10 dictionary.
VAL-ERR-204Drug identifier (CUM) does not match an active INVIMA marketing authorization file.Ensure drug codes strictly follow the [expediente]-[consecutivo] structure from INVIMA’s regulated database.

6. CUV Generation and DIAN Electronic Invoicing Integration

When a payload satisfies every validation constraint, the Sandbox returns an HTTP 200 OK response containing the Unique Validation Code (CUV):

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

💡 Critical Compliance Rule: The CUV issued by MinSalud must be embedded directly into the health-sector XML attachment sent to the DIAN (tax agency). If an invoice is submitted to the DIAN without a valid CUV, insurance payers (EPS) will reject 100% of the reimbursement claim during audit review.


7. MinSalud Interoperability Consulting with DoneAPI

Navigating the MinSalud Sandbox and certifying RIPS JSON compliance does not have to disrupt your clinic’s billing operations or product development roadmap.

At DoneAPI, we support healthcare providers (IPS), HealthTech startups, and diagnostic laboratory networks across Colombia to:

  • Deploy Turnkey mTLS Infrastructure: End-to-end management of digital certificates, private key storage, and secure gateway handshakes.
  • Pre-MinSalud Validation Microservice: Integrate our local validation engine that audits data against official ministerial business rules before dispatch, driving submission rejections down to zero.
  • Legacy EMR to RIPS JSON Migration: Automated pipelines converting existing relational databases into Resolution 2275-compliant payloads.
  • Official Certification Support: Continuous technical accompaniment until full production authorization is secured.

💬 Does your hospital or HealthTech platform need to connect to the MinSalud Sandbox or certify RIPS JSON compliance?
Connect directly with our clinical integration engineers on WhatsApp.

Connect to MinSalud Sandbox & Certify RIPS JSON with DoneAPI

Clear the validation engine, automate mTLS handshakes, and generate CUVs in seconds with zero operational disruption.

Speak with a Digital Health Architect on WhatsApp

8. Conclusion

Passing conformance testing within the MinSalud Sandbox is a structured technical milestone achievable through disciplined security architecture and strict schema alignment with Resolution 2275 of 2023.

By implementing an automated mTLS client, handling OAuth 2.0 token refreshes proactively, and validating clinical rules prior to submission, your healthcare enterprise guarantees seamless integration into Colombia’s digital health infrastructure, protecting cash flow and ensuring continuous statutory compliance.

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