Confirmaciones en Codenica API
Para empezar a trabajar con las Confirmaciones mediante Codenica API, crea una clave API en los ajustes de Codenica. Si todavía no tienes una, abre Codenica API - introducción en una pestaña nueva. Allí se explican las reglas comunes para crear claves, guardar secretos y autenticar peticiones.
Una Confirmación es un registro de proceso en el que un Client concreto debe tomar una decisión. La integración puede preparar los datos, asignar el Client, adjuntar documentos, activos, notas y archivos, y después poner la decisión a disposición del contexto del Client correspondiente.
El nombre técnico de un registro es confirmation y el de la colección en la API es confirmations. Una edición normal modifica la parte descriptiva del registro. No escribas el resultado de la decisión directamente en status - confirma o rechaza la Confirmación mediante el endpoint específico /decision.
Los ejemplos utilizan PUBLIC-API-CONFIRMATION-20260908-0001. Sustitúyelo por un identificador de tu aplicación de integración y reemplaza los valores entre llaves por los datos de tu base de datos.
Confirmaciones - dirección de la API y tipo de instalación
Todas las rutas de Confirmaciones empiezan por:
{BASE_URL}/api/v1/confirmationsBASE_URL es la dirección del servidor de Codenica sin el sufijo /api/v1. En Codenica Cloud, utiliza el dominio o subdominio asignado a la empresa correspondiente:
export BASE_URL="https://{dominio-de-la-empresa}"En la instalación On-Premise predeterminada, Codenica Discovery registra la dirección local:
export BASE_URL="http://codenica.local:5150"Si el administrador ha publicado la instalación con un dominio de empresa, mediante HTTPS, detrás de un proxy inverso o en otro puerto, utiliza la dirección exacta indicada para esa instalación:
export BASE_URL="https://{direccion-real-de-la-instalacion}"Usa localhost solo cuando la integración y la API se ejecuten en el mismo ordenador. El ejemplo http://localhost:5050 corresponde a un entorno de desarrollo local, no a la dirección estándar de On-Premise. No envíes tenantId en el body ni en la cadena de consulta. La base de datos de destino se selecciona a partir del host de la petición.
Confirmaciones - scopes de la clave API
La clave utilizada para las Confirmaciones debe contener únicamente los scopes que necesita la integración. El conjunto completo de scopes del módulo es:
confirmations:read
confirmations:write
confirmations:delete
confirmations:schema
confirmations:stats
confirmations:relationships:read
confirmations:relationships:write
confirmations:users:read
confirmations:files:read
confirmations:files:write
confirmations:technical:read
confirmations:technical:write
confirmations:pin:write
confirmations:decision:write
users:readUsa confirmations:read para listas y registros. La creación y la edición normal requieren confirmations:write, mientras que la eliminación requiere confirmations:delete. Añade los scopes de relaciones, archivos, estadísticas, campos técnicos, fijación y decisiones solo cuando la integración vaya a realizar esas operaciones.
Si la integración selecciona destinos de relaciones de otra colección, también necesita el scope de lectura correspondiente, por ejemplo assets:read, documents:read, clients:read o notes:read. Los scopes de la clave no sustituyen los permisos del usuario asociado a ella.
Confirmaciones - autenticación de peticiones
Autentica cada petición de Codenica API con dos cabeceras:
X-Codenica-Client-Id: {CLIENT_ID}
X-Codenica-Client-Secret: {CLIENT_SECRET}
Accept: application/jsonEjemplo de la primera petición:
export PUBLIC_API_CLIENT_ID="cna_example"
export PUBLIC_API_CLIENT_SECRET="cns_example"
curl --request GET --url "$BASE_URL/api/v1/context" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET"Una integración externa no necesita el Bearer JWT del administrador ni las cookies del panel de Codenica. Guarda el Client Secret en el servidor, dentro de un almacén de secretos. No lo incluyas en código del navegador, repositorios, URL, historial de comandos ni registros. Fuera del desarrollo local, utiliza HTTPS.
Guarda meta.requestId de las respuestas. Sirve para localizar la petición en los registros, pero no sustituye al UUID de la Confirmación ni es un secreto.
Confirmaciones - comprobar el contexto de conexión
Lee el contexto antes de realizar la primera escritura. Así confirmarás que la dirección llega a la base de datos correcta y que la clave tiene los scopes y límites necesarios:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/context"Comprueba, entre otros datos, data.apiVersion, data.contractVersion, los datos de data.tenant, que data.caller.authentication sea api_key, el rol y clientId del emisor, la presencia de confirmations en data.capabilities.resources, además de los scopes y límites.
{
"data": {
"caller": {
"role": "Administrator",
"authentication": "api_key",
"scopes": [
"confirmations:read",
"confirmations:write",
"confirmations:decision:write"
]
},
"capabilities": {
"supportsETag": true,
"supportsIdempotency": true,
"supportsRelationships": true,
"supportsFiles": true
}
},
"meta": { "requestId": "{REQUEST_ID}" }
}Si el contexto muestra otra empresa o falta un scope necesario, corrige la dirección o la clave. No intentes seleccionar otra base de datos enviando un identificador ajeno.
Confirmaciones - esquema y destinos de relaciones
El esquema es la referencia para conocer los campos actuales, sus tipos, si se pueden escribir y los destinos de relaciones permitidos:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/schema"La respuesta incluye, entre otros datos, data.itemType, data.fields y data.relationshipTargets. En este módulo, itemType siempre es confirmation. Para cada campo, comprueba readable, writable, required, technical, unique y maxLength.
{
"data": {
"itemType": "confirmation",
"fields": [
{ "name": "customId", "type": "string", "writable": true },
{ "name": "status", "type": "string", "writable": false },
{ "name": "pin", "type": "integer", "writable": false }
],
"relationshipTargets": [
{ "targetDataSet": "assets" },
{ "targetDataSet": "clients", "targetItemType": "client" },
{ "targetDataSet": "documents", "targetItemType": "document" },
{ "targetDataSet": "notes", "targetItemType": "note" }
]
}
}Para assets, el esquema no impone un único tipo de objeto. Si un destino tiene itemType=computer, envía computer en la petición de relación en lugar de suponer asset. No construyas el mapeo a partir de un solo ejemplo - lee el esquema actual antes de ejecutar la integración.
Confirmaciones - campos de negocio y campos del proceso
Los principales campos que puedes enviar en attributes son:
customIdlocation, departmenttag, linkinfo, descriptiontype, categorystatus, dateConfirmed, dateDeclined, dateEnd, remark, pinEntre las longitudes máximas importantes están: customId 500, location 300, department 300, tag 2000, link 2000, info 10000, type 300, category 300 y description 10000 caracteres. El esquema actual de la base de datos tiene prioridad.
No escribas status, dateConfirmed, dateDeclined, dateEnd, remark ni pin mediante un PATCH normal. Tampoco envíes los campos de auditoría:
creator
updater
dateCreated
dateUpdated
importId
importSource
dateImportedConfirmaciones - endpoints disponibles
Estas son las rutas principales del módulo confirmations:
GET /api/v1/confirmations
POST /api/v1/confirmations
GET /api/v1/confirmations/{CONFIRMATION_ID}
PATCH /api/v1/confirmations/{CONFIRMATION_ID}
DELETE /api/v1/confirmations/{CONFIRMATION_ID}
GET /api/v1/confirmations/schema
GET /api/v1/confirmations/stats
GET /api/v1/confirmations/values
POST /api/v1/confirmations:batch
GET /api/v1/confirmations/{CONFIRMATION_ID}/relationships
POST /api/v1/confirmations/{CONFIRMATION_ID}/relationships
POST /api/v1/confirmations/{CONFIRMATION_ID}/relationships:batch
DELETE /api/v1/confirmations/{CONFIRMATION_ID}/relationships/{DATASET}/{TARGET_ID}
GET /api/v1/confirmations/{CONFIRMATION_ID}/user-relationships
GET /api/v1/confirmations/{CONFIRMATION_ID}/files
POST /api/v1/confirmations/{CONFIRMATION_ID}/files
POST /api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}
DELETE /api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}
GET /api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}/content
POST /api/v1/confirmations/{CONFIRMATION_ID}/pin
POST /api/v1/confirmations/{CONFIRMATION_ID}/decisionLas lecturas requieren scopes de lectura y cada mutación necesita, además, el scope correspondiente a la operación. Toda petición que modifique datos requiere Idempotency-Key; una operación sobre un registro existente también requiere el If-Match actual.
Confirmaciones - listados y paginación
Lee las Confirmaciones por páginas. Puedes enviar el valor fijo itemType=confirmation, aunque la API ya utiliza ese tipo para todo el módulo:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations?itemType=confirmation&page=1&pageSize=25"La respuesta contiene la colección data.items y la información de paginación:
{
"data": {
"items": [
{
"id": "{CONFIRMATION_ID}",
"itemType": "confirmation",
"attributes": {
"customId": "ERP-CONFIRMATION-2026-0042",
"category": "Compras",
"status": "Pending"
},
"meta": { "etag": "{ETAG}" }
}
],
"page": 1,
"pageSize": 25,
"totalItems": 1,
"totalPages": 1,
"hasNextPage": false
},
"meta": { "requestId": "{REQUEST_ID}" }
}Pasa a la página siguiente según hasNextPage. Lee el tamaño máximo de página desde data.capabilities.limits.maxPageSize en lugar de fijarlo en el código.
Confirmaciones - búsqueda y filtros
Usa search para buscar texto en los campos descriptivos. Para sincronizar, suele ser mejor utilizar un customId estable o un UUID:
curl --silent --show-error -G \
--data-urlencode "search=compras" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=20" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations"Puedes combinar filtros de campos en una sola petición:
curl --silent --show-error -G \
--data-urlencode "status=Pending" \
--data-urlencode "category=Compras" \
--data-urlencode "customId=ERP-CONFIRMATION-2026-0042" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations"Para un filtrado más preciso, utiliza la forma estructurada field:operator:value:
category:eq:Compras
status:ne:Declined
description:contains:monitor
customId:startswith:ERP-CONFIRMATION-
link:notempty:Algunos operadores útiles son eq, ne, contains, startswith, endswith y notempty. Codifica en la URL los valores que contengan espacios, dos puntos o caracteres especiales.
Confirmaciones - selección de campos y datos incluidos
El parámetro fields limita los atributos incluidos en la respuesta. Al sincronizar una lista, solicita solo los datos que necesita la integración:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations?fields=id,customId,status,category&page=1&pageSize=20"Para recibir en la misma respuesta los archivos, las relaciones y el usuario creador, utiliza include:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}?fields=%2A&include=files%2Crelationships%2Cusers"Incluir archivos requiere confirmations:files:read, las relaciones requieren confirmations:relationships:read y los usuarios requieren confirmations:users:read. Mantén fields e include ajustados cuando la integración no necesite el registro completo.
Confirmaciones - estadísticas y valores de campos
El endpoint stats ayuda a crear un resumen de las Confirmaciones visibles, mientras que values proporciona valores para los filtros:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/stats?field=category&limit=20"curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/values?field=category&search=com&limit=20"Ambos endpoints son de solo lectura y requieren confirmations:stats. Los resultados solo incluyen registros visibles para el usuario asociado a la clave y no necesitan ETag. Comprueba el valor máximo de limit en el contrato actual de la API.
Confirmaciones - crear un registro y asignar un Client
Una Confirmación que requiere una decisión debe apuntar a un Client empresarial. Es el registro del Client en la base de datos, no la identidad técnica AppUser utilizada para iniciar sesión:
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}El payload mínimo contiene el itemType fijo, los attributes descriptivos y la relación con el Client:
{
"itemType": "confirmation",
"attributes": {
"customId": "ERP-CONFIRMATION-2026-0042",
"category": "Compras",
"description": "Confirmación de la compra de una estación de trabajo."
},
"relationships": [
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}
]
}La asignación puede enviarse durante la creación. No añadas relationshipType a esta relación.
Confirmaciones - ejemplo completo de creación
En una integración más grande, guarda el body en un archivo para poder repetir de forma segura la misma petición después de un fallo temporal de conexión:
{
"itemType": "confirmation",
"attributes": {
"customId": "PUBLIC-API-CONFIRMATION-20260908-0001",
"location": "Madrid",
"department": "IT",
"tag": "integracion,compras,confirmacion",
"link": "https://erp.example.com/requests/0001",
"info": "Solicitud recibida del sistema de compras.",
"type": "Compra de hardware",
"category": "Compras",
"description": "Confirmación de la compra de una nueva estación de trabajo para el departamento de IT."
},
"relationships": [
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "Idempotency-Key: erp-confirmation-create-0001" \
--data-binary @confirmation-create.json \
"$BASE_URL/api/v1/confirmations"Una creación correcta devuelve 201 Created. La respuesta contiene el UUID, itemType, los atributos, las fechas de metadatos, el ETag y requestId. Guarda el UUID y el ETag porque los necesitarás en los pasos siguientes.
Confirmaciones - Idempotency-Key y reintentos seguros
Toda petición que modifique datos mediante una clave API debe tener su propio Idempotency-Key. Si la conexión se interrumpe después de enviar la petición, repite exactamente la misma petición con la misma clave:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: erp-confirmation-create-0001" \
--data-binary @confirmation-create.json \
"$BASE_URL/api/v1/confirmations"Repetir una petición idéntica con la misma clave no debe crear una segunda Confirmación. No reutilices una clave para bodies u operaciones diferentes. Una clave de idempotencia representa una sola operación de negocio.
Creación: Idempotency-Key = erp-confirmation-create-0001
Reintento: Idempotency-Key = erp-confirmation-create-0001
Nueva edición: Idempotency-Key = erp-confirmation-update-0001Utiliza claves distintas para PATCH, fijación, decisiones, relaciones, archivos y eliminación. Después de cada cambio correcto, guarda el ETag devuelto por la operación.
Confirmaciones - leer un registro
Después de crear una Confirmación o recibir su UUID, recupera el registro completo:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}?fields=%2A"Conserva el ETag de la cabecera HTTP ETag o de data.meta.etag. Guarda también meta.requestId para el diagnóstico.
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}?fields=%2A&include=files%2Crelationships%2Cusers"La versión con include permite ver en una sola lectura el Client asignado, las relaciones de objetos, el requester y los archivos. Si solo necesitas datos para sincronizar, limita la respuesta con fields.
Confirmaciones - editar con el ETag actual
Una edición segura sigue siempre esta secuencia: lee el registro, obtiene el ETag actual, prepara un PATCH pequeño, envía If-Match y un nuevo Idempotency-Key y guarda el nuevo ETag:
{
"attributes": {
"info": "Información añadida después de comprobarla en el sistema de compras.",
"category": "Compras de IT",
"description": "Confirmación actualizada por la integración."
}
}curl --fail-with-body --silent --show-error \
--request PATCH \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-update-0001" \
--data-binary @confirmation-update.json \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}"La operación correcta devuelve 200 OK y un ETag nuevo. Un PATCH normal puede cambiar campos descriptivos, pero no debe utilizarse para escribir status, las fechas de decisión, dateEnd, remark ni pin.
Confirmaciones - protección frente a ediciones simultáneas
Si omites If-Match, la API rechaza el cambio:
HTTP 428 Precondition Required
code: if_match_requiredSi envías un ETag anterior a la versión actual del registro, recibirás:
HTTP 412 Precondition Failed
code: if_match_failedDespués de un 412, vuelve a leer el registro, compara sus valores con el cambio que quieres realizar y solo entonces envía un nuevo PATCH. No repitas en bucle la misma petición con un ETag antiguo.
No intentes saltarte el control de versiones colocando campos del proceso en el body:
{
"attributes": {
"status": "Confirmed",
"dateConfirmed": "2026-09-08T10:30:00Z"
}
}Utiliza el endpoint específico /decision. Así el sistema puede comprobar el Client correcto, el estado actual del proceso y la concurrencia.
Confirmaciones - fijar y desfijar
La fijación es una operación independiente y no forma parte de un PATCH normal. Los valores permitidos son null o un número entre 0 y 3:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-pin-0001" \
--data '{"pin":3}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/pin"Para desfijar el registro, envía null:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {PINNED_ETAG}" \
--header "Idempotency-Key: erp-confirmation-unpin-0001" \
--data '{"pin":null}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/pin"Ambas operaciones requieren confirmations:pin:write. Después de cada acción, lee el ETag nuevo y comprueba el valor de pin.
Confirmaciones - decisión del Client
La decisión es una acción de negocio, no una edición normal del registro. Antes de tomarla, la Confirmación debe estar asignada a un Client. La petición debe proceder de una clave que represente a ese Client y tener confirmations:decision:write. La API también comprueba el ETag actual.
Para confirmar una solicitud, utiliza este payload:
{
"confirmed": true,
"remark": "Confirmo que la solicitud puede realizarse."
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_DECISION_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_DECISION_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {DECISION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-decision-0001" \
--data '{"confirmed":true,"remark":"Confirmo que la solicitud puede realizarse."}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/decision"Para rechazarla, utiliza la misma ruta con false:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_DECISION_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_DECISION_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {DECISION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-decision-0002" \
--data '{"confirmed":false,"remark":"Rechazo la solicitud."}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/decision"Después de una decisión positiva, el estado pasa a ser Confirmed y el sistema escribe dateConfirmed, dateEnd y el comentario. Después de una decisión negativa, el estado es Declined y el sistema escribe dateDeclined, dateEnd y el comentario. No establezcas estos campos manualmente.
Confirmaciones - Client y requester
La relación con el Client identifica al Client empresarial que debe tomar la decisión. No es el identificador técnico de AppUser. Lee la asignación junto con las relaciones de objetos o desde un registro individual usando include=relationships.
La API también expone una colección de usuarios independiente y de solo lectura. Contiene el requester automático, es decir, el usuario que creó la Confirmación:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/user-relationships?relationshipType=requester&page=1&pageSize=20"{
"targetId": "{REQUESTER_USER_ID}",
"targetDataSet": "users",
"relationshipType": "requester",
"displayName": "{REQUESTER_NAME}",
"email": "{REQUESTER_EMAIL}",
"role": "{REQUESTER_ROLE}"
}El requester lo asigna el sistema. No establezcas esta relación en attributes ni intentes cambiarla mediante los endpoints de relaciones de objetos. Para leerla necesitas confirmations:users:read.
Confirmaciones - relaciones de objetos permitidas
El catálogo actual de destinos de relaciones de Confirmaciones incluye cuatro colecciones:
assetscomputerclientsclientdocumentsdocument o el tipo devuelto por el destinonotesnoteCada destino debe existir, ser visible para el usuario asociado a la clave y coincidir con la lista relationshipTargets devuelta por el esquema. El catálogo de Confirmaciones no permite relaciones con colecciones arbitrarias.
Confirmaciones - formato de relaciones normales y asignación del Client
Una relación con un activo, documento o nota contiene relationshipType. Ejemplo con un documento:
{
"targetId": "{DOCUMENT_ID}",
"targetDataSet": "documents",
"targetItemType": "invoice",
"relationshipType": "related"
}La asignación del Client es la excepción. Incluye targetDataSet=clients y targetItemType=client, pero no incluye relationshipType:
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}Para los activos, lee el tipo real del objeto y envíalo exactamente en targetItemType:
assets - targetItemType: computer
documents - targetItemType: invoice
notes - targetItemType: noteLos valores anteriores son ejemplos. El tipo correcto puede ser diferente en tu base de datos.
Confirmaciones - añadir, leer y eliminar relaciones
Añade una relación con un POST que contenga directamente el objeto de relación, sin una envoltura adicional:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-relation-add-0001" \
--data '{"targetId":"{DOCUMENT_ID}","targetDataSet":"documents","targetItemType":"invoice","relationshipType":"related"}' \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships"Lee las relaciones como una colección:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships?targetDataSet=documents&relationshipType=related&page=1&pageSize=50"Eliminar una relación requiere el ETag actual de la Confirmación. Coloca la colección y el UUID del destino en la ruta, y envía el tipo de relación en la consulta:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-relation-delete-0001" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships/documents/{DOCUMENT_ID}?relationshipType=related"Añadir o eliminar una relación devuelve una nueva versión del registro o data=true. Lee el ETag nuevo después de cada cambio correcto.
Confirmaciones - cambiar varias relaciones
Para añadir o eliminar varias relaciones en una sola petición, utiliza relationships:batch. El body contiene los arrays add y remove:
{
"add": [
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
}
],
"remove": [
{
"targetId": "{NOTE_ID}",
"targetDataSet": "notes",
"targetItemType": "note",
"relationshipType": "related"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-relationships-batch-0001" \
--data-binary @confirmation-relationships-batch.json \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/relationships:batch"La respuesta contiene los contadores added, removed y skipped. El límite del batch de relaciones procede del contexto, requiere el ETag actual y cambia la versión de la Confirmación. Para asignar un Client, utiliza el formato sin relationshipType.
Confirmaciones - lista y carga de archivos
Primero puedes leer los archivos asociados actualmente a la Confirmación:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files?page=1&pageSize=50"Un elemento de la lista incluye, entre otros datos, id, fileName, contentType, size, relationshipType, isMain y downloadUrl. Añade un archivo como multipart/form-data:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-file-upload-0001" \
--form "[email protected];type=application/pdf" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files?relationshipType=decision-form"{
"data": {
"id": "{FILE_ID}",
"fileName": "formulario-decision.pdf",
"contentType": "application/pdf",
"size": 48231,
"relationshipType": "decision-form",
"isMain": false,
"downloadUrl": "/api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}/content"
}
}La carga requiere confirmations:files:write, el ETag actual y una clave de idempotencia nueva. Lee el límite de tamaño desde data.capabilities.limits.maxUploadBytes. La API de Confirmaciones no ofrece una operación para elegir un archivo principal - no construyas una integración que espere un endpoint /main.
Confirmaciones - descargar, adjuntar y eliminar archivos
Descarga el contenido del archivo mediante el endpoint content y guárdalo en modo binario:
curl --fail-with-body --silent --show-error \
--output formulario-decision-descargado.pdf \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}/content"Si el archivo ya está guardado en Codenica, puedes adjuntarlo a una segunda Confirmación sin volver a cargar su contenido:
curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {SECOND_CONFIRMATION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-file-attach-0001" \
"$BASE_URL/api/v1/confirmations/{SECOND_CONFIRMATION_ID}/files/{FILE_ID}?relationshipType=reference"Para separar un archivo de una Confirmación o eliminar su última relación, utiliza la misma ruta DELETE:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CONFIRMATION_ETAG}" \
--header "Idempotency-Key: erp-confirmation-file-delete-0001" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}/files/{FILE_ID}"Attach crea una relación con un archivo existente. Si el archivo sigue asignado a la Confirmación de origen, separarlo de un segundo registro no debe eliminar la relación de origen. Antes de eliminar la última relación, lee la lista de archivos y comprueba que has seleccionado el elemento correcto.
Confirmaciones - operaciones por lotes
El endpoint /api/v1/confirmations:batch permite combinar la creación, edición y eliminación de registros. El formato utiliza un array items y objetos independientes create y update:
{
"items": [
{
"operation": "create",
"create": {
"itemType": "confirmation",
"attributes": {
"customId": "ERP-BATCH-CONFIRMATION-A",
"category": "Accesos",
"description": "Primera Confirmación creada en una operación por lotes."
},
"relationships": [
{
"targetId": "{CLIENT_ID}",
"targetDataSet": "clients",
"targetItemType": "client"
}
]
}
},
{
"operation": "update",
"id": "{EXISTING_ID}",
"ifMatch": "{EXISTING_ETAG}",
"update": {
"attributes": {
"description": "Descripción actualizada en una operación por lotes."
}
}
},
{
"operation": "delete",
"id": "{RECORD_TO_DELETE_ID}",
"ifMatch": "{RECORD_TO_DELETE_ETAG}"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: erp-confirmations-batch-0001" \
--data-binary @confirmations-batch.json \
"$BASE_URL/api/v1/confirmations:batch"{
"data": {
"items": [
{
"index": 0,
"operation": "create",
"status": 201,
"id": "{CREATED_ID}",
"data": { "meta": { "etag": "{CREATED_ETAG}" } }
}
],
"succeeded": 1,
"failed": 0
}
}Cada elemento de actualización o eliminación necesita su propio ifMatch actual. Un batch no es una transacción global. Si el resultado es parcial, la API puede devolver 207 Multi-Status; analiza cada elemento por separado y no repitas operaciones que ya hayan terminado correctamente.
Confirmaciones - eliminar un registro
Antes de eliminarlo, vuelve a leer el registro, verifica el UUID y el ETag actual y envía la petición con una clave de idempotencia distinta:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: {CURRENT_ETAG}" \
--header "Idempotency-Key: erp-confirmation-delete-0001" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}"Una respuesta correcta devuelve 200 OK y data=true. Después de eliminarlo, comprueba que el UUID ya no esté disponible:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/confirmations/{CONFIRMATION_ID}"El resultado esperado es 404 Not Found con el código confirmation_not_found. Eliminar una Confirmación no elimina automáticamente los documentos, activos o notas relacionados.
Confirmaciones - errores, límites y secuencia segura
Los errores utilizan el formato Problem Details. Registra status, code y requestId, pero nunca el Client Secret ni las cabeceras completas:
validation_failedauthentication_required o authentication_failedconfirmation_client_requiredconfirmation_not_foundconfirmation_unique_constraint o confirmation_concurrency_conflictif_match_failed, if_match_requiredconfirmation_decision_rejected, confirmation_pin_rejectedrate_limit_exceededRetry-After.Lee X-RateLimit-Limit y X-RateLimit-Remaining. Guarda en caché el esquema y los valores de campos, limita la concurrencia y aplica backoff después de 429.
Una secuencia segura es: context, schema, elegir el Client, listar o leer, crear con Idempotency-Key, guardar UUID y ETag, añadir relaciones o archivos, editar con If-Match, fijar, decidir mediante /decision, verificar leyendo el registro y solo después eliminarlo. La misma secuencia puede implementarse en n8n pasando el UUID, el ETag y las claves de idempotencia entre los pasos.
