Actualización de templates
Este servicio permite actualizar plantillas personalizadas que posteriormente se pueden utilizar para diligenciar de documentos para firma.
/templatellave privadaprk_Autenticación
Incluye tu llave privada en el encabezado Authorization.
Authorization: prk_xxx...
Parámetros de actualización
| Nombre | Tipo | Descripción |
|---|---|---|
id | String requerido | Identificador de la plantilla. |
name | String requerido | Nombre de la automatización. |
description | String opcional | Texto que describe la plantilla, máximo 500 caracteres. |
config | Array requerido | Arreglo de preguntas para el usuario. Consulta Configuración JSON. |
signatureProfile | Array requerido | Definición de firmantes y aprobadores. Consulta Perfiles de Firma. |
sign | Array requerido | Nombres de preguntas obligatorias. |
preBuild | Boolean opcional | Si es true, incluye prellenado automático. |
PUT /template valida el cuerpo igual que POST /template: name, config, sign y signatureProfile son obligatorios aunque no cambien, y la API responde 400 si falta alguno. Lo más seguro es partir de lo que devuelve GET /template?id=, modificar lo que necesites y enviarlo de vuelta sin urls, que la API no acepta en la escritura.
description se conserva si no lo envíasOmitir description en el PUT no borra la descripción que ya tiene la plantilla: se queda la
anterior. Para cambiarla, envía el nuevo texto —máximo 500 caracteres, o la API responde 400—.
Hoy no hay forma de dejar una plantilla sin descripción una vez que la tiene: la validación rechaza
tanto el string vacío ("") como null, y omitir el campo conserva el valor anterior. Si necesitas
que el texto deje de mostrarse, reemplázalo por el que corresponda.
Ejemplos de Actualización
- curl
- Python
- Node.js
curl -X PUT https://api.auco.ai/v1.5/ext/template \
-H "Content-Type: application/json" \
-H "Authorization: prk_private_key_company" \
-d '{
"id": "64823dc5ce28a265e02d68f3",
"name": "Documento de prueba modificación variables",
"description": "Contrato de servicios con un firmante, para el equipo comercial",
"config": [
{
"name": "nueva_pregunta",
"type": "name",
"description": "Ejemplo de nueva pregunta"
},
{
"name": "nombre_cliente",
"type": "name",
"description": "Ingrese el nombre del cliente"
},
{
"description": "Seleccione el tipo de documento para el cliente",
"name": "tipo_documento_cliente",
"type": "clausula",
"value": "cc",
"options": [
{
"name": "Cédula de Ciudadanía",
"value": "cc"
},
{
"name": "Cédula de extranjería",
"value": "ce"
}
]
},
{
"description": "Digite el número de cédula de ciudadanía para el cliente",
"name": "cedula_cliente",
"type": "number",
"prereq": [
{
"k": "tipo_documento_cliente",
"v": "cc"
}
]
},
{
"description": "Digite el número de cédula de extranjería para el cliente",
"name": "cedula_extranjeria_cliente",
"type": "number",
"prereq": [
{
"k": "tipo_documento_cliente",
"v": "ce"
}
]
},
{
"name": "correo_cliente",
"type": "email",
"description": "Ingrese el correo del cliente"
},
{
"name": "telefono_cliente",
"type": "phone",
"description": "Ingrese el teléfono del cliente"
}
],
"sign": [
"nombre_cliente",
"cedula_cliente",
"cedula_extranjeria_cliente",
"correo_cliente",
"telefono_cliente",
"nueva_pregunta"
],
"signatureProfile": [
{
"email": "correo_cliente",
"phone": "telefono_cliente",
"identification": "cedula_cliente|cedula_extranjeria_cliente",
"name": "nombre_cliente",
"type": "cliente"
}
]
}'
import requests
import json
template_data = {
"id": "64823dc5ce28a265e02d68f3",
"name": "Documento de prueba modificación variables",
"description": "Contrato de servicios con un firmante, para el equipo comercial",
"config": [
{
"name": "nueva_pregunta",
"type": "name",
"description": "Ejemplo de nueva pregunta"
},
{
"name": "nombre_cliente",
"type": "name",
"description": "Ingrese el nombre del cliente"
},
{
"description": "Seleccione el tipo de documento para el cliente",
"name": "tipo_documento_cliente",
"type": "clausula",
"value": "cc",
"options": [
{
"name": "Cédula de Ciudadanía",
"value": "cc"
},
{
"name": "Cédula de extranjería",
"value": "ce"
}
]
},
{
"description": "Digite el número de cédula de ciudadanía para el cliente",
"name": "cedula_cliente",
"type": "number",
"prereq": [
{
"k": "tipo_documento_cliente",
"v": "cc"
}
]
},
{
"description": "Digite el número de cédula de extranjería para el cliente",
"name": "cedula_extranjeria_cliente",
"type": "number",
"prereq": [
{
"k": "tipo_documento_cliente",
"v": "ce"
}
]
},
{
"name": "correo_cliente",
"type": "email",
"description": "Ingrese el correo del cliente"
},
{
"name": "telefono_cliente",
"type": "phone",
"description": "Ingrese el teléfono del cliente"
}
],
"sign": [
"nombre_cliente",
"cedula_cliente",
"cedula_extranjeria_cliente",
"correo_cliente",
"telefono_cliente",
"nueva_pregunta"
],
"signatureProfile": [
{
"email": "correo_cliente",
"phone": "telefono_cliente",
"identification": "cedula_cliente|cedula_extranjeria_cliente",
"name": "nombre_cliente",
"type": "cliente"
}
]
}
def update_template():
url = "https://api.auco.ai/v1.5/ext/template"
headers = {
"Content-Type": "application/json",
"Authorization": "prk_private_key_company"
}
try:
response = requests.put(
url,
json=template_data,
headers=headers
)
response.raise_for_status()
result = response.json()
print("Template actualizado correctamente!")
print(f"Mask URL: {result['urls']['mask']}")
print(f"Complete URL: {result['urls']['complete']}")
return result
except requests.exceptions.RequestException as error:
print(f"Error actualizando template: {error.response.json() if hasattr(error, 'response') else error}")
if __name__ == "__main__":
update_template()
const axios = require('axios');
const templateData = {
id: '64823dc5ce28a265e02d68f3',
name: 'Documento de prueba modificación variables',
description: 'Contrato de servicios con un firmante, para el equipo comercial',
config: [
{
name: 'nueva_pregunta',
type: 'name',
description: 'Ejemplo de nueva pregunta',
},
{
name: 'nombre_cliente',
type: 'name',
description: 'Ingrese el nombre del cliente',
},
{
description: 'Seleccione el tipo de documento para el cliente',
name: 'tipo_documento_cliente',
type: 'clausula',
value: 'cc',
options: [
{
name: 'Cédula de Ciudadanía',
value: 'cc',
},
{
name: 'Cédula de extranjería',
value: 'ce',
},
],
},
{
description: 'Digite el número de cédula de ciudadanía para el cliente',
name: 'cedula_cliente',
type: 'number',
prereq: [
{
k: 'tipo_documento_cliente',
v: 'cc',
},
],
},
{
description: 'Digite el número de cédula de extranjería para el cliente',
name: 'cedula_extranjeria_cliente',
type: 'number',
prereq: [
{
k: 'tipo_documento_cliente',
v: 'ce',
},
],
},
{
name: 'correo_cliente',
type: 'email',
description: 'Ingrese el correo del cliente',
},
{
name: 'telefono_cliente',
type: 'phone',
description: 'Ingrese el teléfono del cliente',
},
],
sign: [
'nombre_cliente',
'cedula_cliente',
'cedula_extranjeria_cliente',
'correo_cliente',
'telefono_cliente',
'nueva_pregunta',
],
signatureProfile: [
{
email: 'correo_cliente',
phone: 'telefono_cliente',
identification: 'cedula_cliente|cedula_extranjeria_cliente',
name: 'nombre_cliente',
type: 'cliente',
},
],
};
async function updateTemplate() {
try {
const response = await axios.put('https://api.auco.ai/v1.5/ext/template', templateData, {
headers: {
'Content-Type': 'application/json',
Authorization: 'prk_private_key_company',
},
});
console.log('Template actualizado correctamente!');
console.log('Mask URL:', response.data.urls.mask);
console.log('Complete URL:', response.data.urls.complete);
return response.data;
} catch (error) {
console.error('Error actualizando template:', error.response?.data || error.message);
}
}
updateTemplate();
Ejemplo de respuesta
{
"urls": {
"mask": "https://signed_url_mask",
"complete": "https://signed_url_complete"
}
}
Carga de HTML Complete y HTML Mask:
Nuevamente deberás cargar los archivos HTML. En la respuesta del servicio de actualización encontrarás dos URLs firmadas, una
para cada HTML. Tienen una vida útil de 120 segundos: después ya no son válidas. Ten listos los archivos HTML Complete y
HTML Mask antes de actualizar la plantilla y sube cada uno, tal cual, con una petición PUT a su URL.
Content-Type: binary/octet-streamLas URLs están firmadas para ese tipo de contenido: si envías otro —por ejemplo text/html—, la carga se rechaza. Envía el archivo sin transformarlo: en curl usa --data-binary, no -d, que elimina los saltos de línea.
- curl
- Python
- Node.js
# Cargar HTML Mask
curl -X PUT https://signed_url_mask \
-H "Content-Type: binary/octet-stream" \
--data-binary @mask.html
# Cargar HTML Complete
curl -X PUT https://signed_url_complete \
-H "Content-Type: binary/octet-stream" \
--data-binary @complete.html
import requests
def upload_html_files(mask_url, complete_url):
"""
Carga los archivos HTML en las URLs firmadas
Args:
mask_url (str): URL firmada para el HTML Mask
complete_url (str): URL firmada para el HTML Complete
"""
try:
# Leer archivos HTML
with open('mask.html', 'rb') as f:
mask_html = f.read()
with open('complete.html', 'rb') as f:
complete_html = f.read()
headers = {'Content-Type': 'binary/octet-stream'}
# Cargar Mask HTML
response_mask = requests.put(mask_url, data=mask_html, headers=headers)
print(f"Mask HTML cargado: {response_mask.status_code}")
# Cargar Complete HTML
response_complete = requests.put(complete_url, data=complete_html, headers=headers)
print(f"Complete HTML cargado: {response_complete.status_code}")
except requests.exceptions.RequestException as error:
print(f"Error al cargar: {error}")
# Uso desde la respuesta anterior
mask_url = "https://signed_url_mask"
complete_url = "https://signed_url_complete"
upload_html_files(mask_url, complete_url)
const fs = require('fs');
const axios = require('axios');
/**
* Carga los archivos HTML en las URLs firmadas
* @param {string} maskUrl - URL firmada para el HTML Mask
* @param {string} completeUrl - URL firmada para el HTML Complete
*/
async function uploadHtmlFiles(maskUrl, completeUrl) {
try {
// Leer archivos HTML
const maskHtml = fs.readFileSync('mask.html');
const completeHtml = fs.readFileSync('complete.html');
const headers = { 'Content-Type': 'binary/octet-stream' };
// Cargar Mask HTML
await axios.put(maskUrl, maskHtml, { headers });
console.log('Mask HTML cargado correctamente');
// Cargar Complete HTML
await axios.put(completeUrl, completeHtml, { headers });
console.log('Complete HTML cargado correctamente');
} catch (error) {
console.error('Error al cargar archivos:', error.message);
}
}
// Uso desde la respuesta anterior
const maskUrl = 'https://signed_url_mask';
const completeUrl = 'https://signed_url_complete';
uploadHtmlFiles(maskUrl, completeUrl);
Si expiran antes de subir los archivos, vuelve a llamar PUT /template: cada llamada devuelve URLs nuevas.
Si solo estás actualizando config, sign o signatureProfile y el HTML sigue igual, puedes ignorar las URLs devueltas y no subir nada. El servidor conservará los HTMLs de la versión anterior.
⚠️ Respuestas de error
Los errores llegan con el cuerpo { "message": "..." }.
| Código | Descripción |
|---|---|
| 400 | Cuerpo inválido o plantilla no encontrada: DOCUMENT_NOT_FOUND (el id no corresponde a una plantilla de tu organización), PAYLOAD_NOT_VALID (el cuerpo no es JSON), PROFILE_FIELD_NOT_FOUND: <campo> (el email o phone de un firmante no es una pregunta de config ni un campo de preFill), PROFILE_FIELD_TYPE_INVALID: <campo> must be type <tipo> (apunta a una pregunta de otro tipo), o el mensaje del validador |
| 401 | Autenticación inválida o ausente |
El mensaje del validador nombra el campo que falla, por ejemplo "signatureProfile" is required, "config[0].maxLength" is not allowed o "signatureProfile[0].name" must be a string. Consulta las reglas de cada campo en Configuración JSON.
La validación de email y phone en signatureProfile es más reciente que muchas plantillas. Una plantilla que se sigue diligenciando sin problema puede ser rechazada por el PUT con PROFILE_FIELD_TYPE_INVALID, casi siempre porque el correo del firmante se pide con una pregunta text. Cambia el tipo de esa pregunta a email en el mismo PUT.