Saltar al contenido principal

🔐 Certificado de Firma Digital

Autenticación Requerida

Incluir en todos los endpoints de esta sección el header: Authorization: Bearer {token}

El certificado de firma digital (.p12 o .pfx) es indispensable para la emisión y firma electrónica de los documentos fiscales ante la DIAN. Solo se puede tener un certificado activo por empresa.

Parámetro Multi-Tenant: client_uuid

Si operas como Casa de Software, puedes administrar los certificados de tus clientes agregando ?client_uuid={{client_uuid}}.

GET {{url}}/company/customers
Authorization: Bearer {token}
🎁 Certificados incluidos en el plan

Algunos planes pagados incluyen cupos de certificado de firma digital en la plataforma de certificados MATICERTS. Al activarse el plan, la empresa titular recibe automáticamente los cupos que incluye; no hay que llamar a ningún endpoint.

  • Cuándo se otorgan: en la compra, la renovación y el cambio a un plan inferior. En los planes pagados de Casa de Software, solo en la primera compra de un plan pagado. El cambio a un plan superior no otorga cupos nuevos, porque el cupo llegó con la compra original.
  • Cupos actuales: 1 en los planes PYME y Paquete por NIT, y 1 en los planes de Casa de Software desde 10.000 documentos. El plan FREE y el plan de Arrendamiento no incluyen cupos por ahora.
  • No reciben cupos: los planes FREE o sin cupos incluidos, las sub-cuentas (clientes) de una Casa de Software y el ambiente sandbox.

🔐 Gestión del Certificado​

GET /certificate — Obtener Certificado Activo
GET {{url}}/certificate?client_uuid={{client_uuid}}
Authorization: Bearer {token}
Content-Type: application/json

Descripción: Obtiene los metadatos del certificado de firma digital actualmente registrado para la empresa emisora.

Parámetros:

NombreUbicaciónRequeridoDescripción
client_uuidqueryNoUUID del cliente (Casa de Software).
✅ Respuesta Exitosa (HTTP 200)
{
"dataRecords": {
"data": {
"id": 1,
"name": "9001234561.p12",
"description": "EMPRESA DEMO SAS",
"extension": ".p12",
"expiration_date": "09-07-2028 02:56:30 pm",
"timestamp": "2026-07-13 23:06:11"
}
},
"success": true
}
POST /certificate — Cargar Certificado Digital
POST {{url}}/certificate?client_uuid={{client_uuid}}
Authorization: Bearer {token}
Content-Type: application/json

Descripción: Carga un nuevo archivo .p12 o .pfx codificado en Base64 junto con su contraseña privada. Si la empresa ya tiene un certificado, usa PUT /certificate/{id} para reemplazarlo.

💡 Guía para Desarrolladores — Envío del Certificado en Base64

El body lleva una sola propiedad, records, cuyo valor es un JSON serializado como texto con las propiedades data, password y description.

El archivo binario .p12 o .pfx debe convertirse a Base64 y enviarse en la propiedad data con el prefijo Data URI data:application/x-pkcs12;base64,. La API descarta todo lo que va hasta la primera coma: sin el prefijo, el Base64 llega recortado y el certificado no se puede leer.

import fs from 'fs';
import axios from 'axios';

// 1. Leer el archivo .p12 y convertir a Base64 con el prefijo Data URI
const p12Buffer = fs.readFileSync('certificado.p12');
const base64Certificate = 'data:application/x-pkcs12;base64,' + p12Buffer.toString('base64');

// 2. Definir los datos del certificado
const records = {
data: base64Certificate,
password: "password_del_certificado",
description: "Certificado digital de producción"
};

// 3. Enviar la petición serializada
const response = await axios.post(`${url}/certificate`, {
records: JSON.stringify(records)
}, {
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
});

Parámetros:

NombreUbicaciónRequeridoDescripción
client_uuidqueryNoUUID del cliente (Casa de Software).
recordsbody✅ SíJSON serializado como texto con las propiedades de abajo.

Propiedades de records:

CampoTipoRequeridoDescripción
datastring✅ SíArchivo .p12 o .pfx en Base64, con el prefijo Data URI data:application/x-pkcs12;base64,.
passwordstring✅ SíContraseña privada del certificado.
descriptionstring✅ SíDescripción identificativa del certificado.
El nombre de la propiedad es data

Si el archivo se envía en una propiedad con otro nombre (por ejemplo, certificate), la API responde 500 con el mensaje Error interno del servidor. El certificado es requerido.. Si falta password o description, la respuesta también es un 500.

✅ Respuesta Exitosa (HTTP 200)

El nombre del archivo se genera con el NIT y el dígito de verificación de la empresa. La contraseña y el contenido del certificado no se devuelven.

{
"dataRecords": {
"data": {
"id": 1,
"name": "9001234561.p12",
"description": "Certificado digital de producción",
"extension": ".p12",
"expiration_date": "09-07-2028 02:56:30 pm"
}
},
"success": true
}
❌ Errores
HTTPMensajeCausa
422El campo records es requerido / El campo records debe ser un JSON válidoFalta records o su valor no es un JSON válido.
400The given data was invalid. / The certificate could not be read. ...El contenido de data no es Base64 válido, se envió sin el prefijo Data URI, el archivo no es un .p12 válido o la contraseña es incorrecta.
500Error interno del servidor. Ya existe un certificado para esta empresa.La empresa ya tiene un certificado. Usa PUT /certificate/{id}.
500Error interno del servidor. El certificado es requerido.Falta la propiedad data en records.

Las respuestas 500 incluyen un campo reference para que soporte ubique el caso:

{
"success": false,
"message": "Error interno del servidor. Ya existe un certificado para esta empresa.",
"reference": "3f1c2a9e-7b4d-4e8a-9c61-0d2b5e8f7a14"
}
PUT /certificate/{id} — Actualizar / Renovar Certificado
PUT {{url}}/certificate/{id}?client_uuid={{client_uuid}}
Authorization: Bearer {token}
Content-Type: application/json

Descripción: Reemplaza el certificado digital de la empresa (por ejemplo, al renovarlo). El body tiene el mismo formato que la creación (POST /certificate). La ruta exige un {id} (puedes usar el id que devuelve GET /certificate); se actualiza siempre el certificado de la empresa autenticada o de la indicada en client_uuid. PUT /certificate sin {id} responde 405.

Parámetros:

NombreUbicaciónRequeridoDescripción
idpath✅ SíID del certificado.
client_uuidqueryNoUUID del cliente (Casa de Software).
recordsbody✅ SíJSON serializado como texto con data (Base64 con el prefijo Data URI), password y description. Las tres propiedades son obligatorias.
{
"records": "{\"data\":\"data:application/x-pkcs12;base64,MIIKgAIBAz...\",\"password\":\"password_del_certificado\",\"description\":\"Certificado digital renovado\"}"
}
✅ Respuesta Exitosa (HTTP 200)
{
"dataRecords": {
"data": {
"id": 1,
"name": "9001234561.p12",
"description": "Certificado digital renovado",
"extension": ".p12",
"expiration_date": "15-08-2029 10:12:45 am",
"timestamp": "2026-10-21 08:30:00"
}
},
"success": true
}
❌ Errores
HTTPMensajeCausa
422El campo records es requerido / El campo records debe ser un JSON válidoFalta records o su valor no es un JSON válido.
400The given data was invalid. / The certificate could not be read. ...El contenido no es Base64 válido, el archivo no es un .p12 válido o la contraseña es incorrecta.
500Error interno del servidor. No existe un certificado para esta empresa.La empresa aún no tiene certificado. Usa POST /certificate.
500Error interno del servidor. El contenido del certificado es requerido.Falta la propiedad data en records.
500Error interno del servidor. El certificado es requerido.data se envió sin el prefijo Data URI.
GET /certificate/expiration/{dni} — Validar Expiración del Certificado
GET {{url}}/certificate/expiration/{dni}
Authorization: Bearer {token}
Content-Type: application/json

Descripción: Verifica la fecha de expiración y vigencia del certificado digital a partir del NIT de la empresa.

Parámetros:

NombreUbicaciónRequeridoDescripción
dnipath✅ SíNIT de la empresa a consultar (sin dígito de verificación ni guiones).
✅ Respuesta Exitosa (HTTP 200)
{
"dataRecords": {
"data": {
"expiration_date": "2028-07-09 14:56:30"
}
},
"success": true
}