Tareas en Codenica API
Antes de enviar la primera solicitud de una tarea, cree una clave API en los ajustes de Codenica. Si todavía no dispone de una, abra Codenica API - Introducción en una pestaña nueva. Allí se explican las reglas comunes para crear claves, autenticar solicitudes, elegir direcciones de API y guardar el Secret de forma segura.
Una tarea representa una actividad concreta, una responsabilidad o un trabajo que debe completarse. Un registro puede contener una fecha límite, estado, prioridad, categoría, descripción, ubicación, departamento, enlace y etiquetas. También puede relacionarse con otros objetos utilizados en Service Desk y en la gestión de activos.
En el contrato de la API, un registro tiene itemType igual a worktask, mientras que la colección del endpoint se llama worktasks. Los ejemplos contienen valores de demostración seguros. Sustituya los identificadores, las direcciones y las fechas por los valores de su integración.
Tareas - dirección de API y elección de instalación
Todas las rutas de tareas comienzan por:
{BASE_URL}/api/v1/worktasksBASE_URL es la dirección de la aplicación Codenica sin el sufijo /api/v1. No añada el nombre de la base de datos ni un identificador de la empresa a la dirección.
Codenica Cloud: use el dominio o subdominio asignado a la empresa:
export BASE_URL="https://{your-company-domain}"Codenica On-Premise: la dirección predeterminada registrada localmente por Codenica Discovery es:
export BASE_URL="http://codenica.local:5150"Si la instalación está publicada mediante un dominio de la empresa, HTTPS, un proxy inverso u otro puerto, use la dirección exacta de esa instalación. Encontrará los detalles en la guía de instalación de Codenica On-Premise. Use localhost únicamente en un entorno de pruebas local preparado expresamente, donde el cliente HTTP y la API se ejecuten en el mismo ordenador.
No envíe tenantId en el body ni en los parámetros de consulta. La base de datos correcta se selecciona a partir de la dirección y el host de la solicitud.
Tareas - clave API y límites de licencia
Cree la clave en Ajustes -> API -> Claves API. Una clave independiente para cada aplicación y entorno facilita el control del acceso. Asigne a la clave un nombre claro y seleccione únicamente los scopes necesarios para las tareas.
Al eliminar una clave, su registro se elimina y se libera un lugar dentro del límite. La fecha de caducidad detiene la autenticación, pero no sustituye el mantenimiento de la lista de claves. Si no se selecciona una fecha final, el periodo activo predeterminado es de 90 días; el periodo máximo de una clave es de 5 años.
Tareas - autenticación de solicitudes
Autentique cada solicitud a Codenica API con dos headers:
X-Codenica-Client-Id: {CLIENT_ID}
X-Codenica-Client-Secret: {CLIENT_SECRET}
Accept: application/jsonEjemplo de la primera lectura:
export PUBLIC_API_CLIENT_ID="cna_your_client_id"
export PUBLIC_API_CLIENT_SECRET="cns_your_client_secret"
curl --fail-with-body --silent --show-error --header "Accept: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" "$BASE_URL/api/v1/context"Una integración externa no necesita una sesión del panel ni el Bearer JWT del usuario. Guarde el Secret en el servidor o en un gestor de secretos. No lo incluya en código del navegador, un repositorio, una URL, el historial del shell ni los logs.
Tareas - comprobar el contexto de conexión
Lea el context antes de descargar una lista o crear la primera tarea. Así comprobará que la dirección conduce 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" | jqCompruebe en la respuesta data.tenant.id, data.tenant.name, data.tenant.subdomain, data.tenant.resolvedDomain, data.caller.clientId y data.caller.scopes. Compruebe también que capabilities incluye supportsRelationships, supportsFiles, supportsETag y supportsIdempotency.
{
"data": {
"apiVersion": "v1",
"caller": {
"authentication": "api_key",
"clientId": "{CLIENT_ID}",
"scopes": [
"worktasks:read",
"worktasks:write"
]
},
"capabilities": {
"supportsETag": true,
"supportsIdempotency": true,
"supportsRelationships": true,
"supportsFiles": true
}
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}Si el context apunta a otra empresa o no incluye el scope necesario, detenga la integración y corrija la dirección o la clave. No intente cambiar de base de datos añadiendo un identificador externo al body.
Tareas - esquema y campos disponibles
El esquema es la fuente de referencia para la configuración actual de las tareas. Devuelve los tipos de campo, los valores obligatorios, la posibilidad de escritura, los campos técnicos y los destinos de relaciones disponibles en la instalació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/worktasks/schema" | jq{
"data": {
"itemType": "worktask",
"fields": [
{
"name": "customId",
"type": "string",
"readable": true,
"writable": true,
"required": false
},
{
"name": "title",
"type": "string",
"readable": true,
"writable": true,
"required": false
}
],
"relationshipTargets": [
{
"targetDataSet": "assets",
"targetItemType": "asset"
},
{
"targetDataSet": "tickets",
"targetItemType": "ticket"
}
]
}
}No dé por hecho que todas las bases de datos tienen la misma configuración. Antes de mapear los campos, lea el esquema actual y respete readable, writable, required, technical y maxLength.
Tareas - campos de escritura y campos del sistema
Los siguientes campos están pensados para attributes. Si el esquema de la instalación actual indica otros límites, el esquema tiene prioridad.
customIddateDuedateEndlocationdepartmenttaglinktitlestatusprioritycategorydescriptionEl campo pin es de solo lectura y se modifica mediante la ruta específica /pin. El sistema completa campos técnicos como authorId, agentId, workTimeId, creator, updater, dateCreated, dateUpdated, importId, importSource y dateImported. No los envíe en una creación normal ni en un PATCH. El valor de itemType siempre debe ser worktask.
Tareas - endpoints principales
La siguiente lista presenta las operaciones principales disponibles para el objeto worktask. Añada únicamente el scope necesario para la operación que vaya a realizar.
Tareas - listas y paginación
Lea la lista de tareas página por página. Establezca el orden de forma explícita para que las lecturas posteriores utilicen una secuencia predecible:
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/worktasks?page=1&pageSize=25&sort=dateCreated&direction=desc" | jqLea data.items, page, pageSize, totalItems, totalPages y hasNextPage en la respuesta. Cuando hasNextPage sea true, solicite la página siguiente. Compruebe el tamaño máximo de página en data.capabilities.limits.maxPageSize del context.
Use ids para solicitar UUID seleccionadas. Para sincronizar datos, conviene conservar un customId estable en la aplicación que realiza la integración y guardar después la UUID devuelta por Codenica API.
Tareas - búsqueda y filtros
La lista admite búsqueda de texto, coincidencias en campos seleccionados y un filtro estructural. Entre los parámetros habituales están customId, search, title, status, priority, category, location, department, tag, createdAfter, createdBefore, updatedAfter y updatedBefore.
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/worktasks?search=puesto&filter=status%3Aeq%3AOpen&sort=dateDue&direction=asc&page=1&pageSize=25" | jqUn filtro tiene la forma field:operator:value. Ejemplos de operadores:
status:eq:Open
priority:ne:Low
title:startswith:Preparar
description:contains:ordenador
dateDue:gte:2026-09-01T00:00:00ZLas abreviaturas =, !=, ge, le, sw y ew corresponden a igualdad, desigualdad, mayor o igual, menor o igual, startswith y endswith. Codifique en la URL los valores que contengan caracteres especiales.
Tareas - selección de campos y datos incluidos
Use fields para limitar los campos devueltos en un registro. Así la respuesta ocupa menos y resulta más fácil de procesar:
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/worktasks?fields=customId,title,status,priority,dateDue&page=1&pageSize=25" | jqUse include cuando necesite datos relacionados:
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/worktasks/{WORKTASK_ID}?fields=%2A&include=files%2Crelationships%2Cusers" | jqLos datos incluidos no amplían los permisos de la clave. Para ver archivos, relaciones o usuarios, la clave necesita worktasks:files:read, worktasks:relationships:read y worktasks:users:read. Use fields=* únicamente cuando realmente necesite campos técnicos.
Tareas - estadísticas y valores de campos
Las estadísticas permiten preparar resúmenes sin descargar toda la colección. Ejemplo: contar las tareas por estado:
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/worktasks/stats?field=status&limit=20" | jq{
"data": {
"total": 42,
"field": "status",
"values": [
{ "value": "Open", "count": 12 },
{ "value": "In progress", "count": 18 },
{ "value": "Closed", "count": 12 }
]
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}El endpoint values devuelve los valores de un campo que coinciden con una búsqueda. Por ejemplo, resulta útil para mostrar sugerencias en un formulario:
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/worktasks/values?field=category&search=inc&limit=20" | jqAmbas rutas son de solo lectura y requieren el scope worktasks:stats.
Tareas - creación mínima
Una escritura mínima debe contener itemType y un objeto attributes. En la práctica, establezca desde el principio su propio customId y el título:
{
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Preparar puesto de trabajo",
"status": "Open",
"priority": "High",
"category": "IT"
}
}Solicitud que crea el registro:
curl --fail-with-body --silent --show-error --request POST --header "Accept: application/json, application/problem+json" --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "Idempotency-Key: erp-worktask-create-2026-0042" --data-raw '{
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Preparar puesto de trabajo",
"status": "Open",
"priority": "High",
"category": "IT"
}
}' "$BASE_URL/api/v1/worktasks" | jqUna respuesta correcta tiene el estado 201 Created. Guarde data.id y el ETag del registro para continuar trabajando con él.
Tareas - creación completa
El siguiente ejemplo registra los datos que normalmente un sistema de planificación envía a una tarea:
{
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Preparar un puesto para una persona nueva",
"description": "Instala el ordenador, configura el acceso a la red y confirma que el puesto está preparado.",
"status": "Open",
"priority": "High",
"category": "Incorporación",
"dateDue": "2026-09-30T12:00:00Z",
"location": "Cracovia",
"department": "IT",
"tag": "onboarding,puesto-de-trabajo",
"link": "https://portal.example.com/tasks/ERP-WORKTASK-2026-0042"
}
}Los valores de status, priority y category deben coincidir con la configuración de su base de datos. La API no crea automáticamente un nuevo diccionario porque una integración envíe un nombre que aún no existe.
curl --fail-with-body --silent --show-error --request POST --header "Accept: application/json, application/problem+json" --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "Idempotency-Key: erp-worktask-create-2026-0042" --data-binary @worktask.json "$BASE_URL/api/v1/worktasks" | jqTareas - Idempotency-Key y reintentos seguros
Toda mutación realizada con una clave API necesita el header Idempotency-Key. El valor identifica una intención de negocio. Para repetir la misma solicitud, conserve la misma clave y no cambie el body. Genere un valor diferente para una tarea nueva o para otra operación.
--header "Idempotency-Key: erp-worktask-create-2026-0042"Si la conexión se interrumpe después de enviar la solicitud, repita primero la solicitud idéntica con la misma clave. No cree inmediatamente una clave nueva, porque podría generar un duplicado. Sin este header, la mutación termina con 428 y el código idempotency_key_required.
Tareas - leer un registro
Después de crear el registro, léalo con la UUID devuelta en data.id:
export WORKTASK_ID="{UUID_FROM_CREATE_RESPONSE}"
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/worktasks/$WORKTASK_ID?fields=customId,title,status,priority,category,dateDue,description" | jqUn registro individual contiene id, itemType, attributes y meta. Lea el ETag en meta; lo necesitará para la siguiente mutación.
{
"data": {
"id": "{WORKTASK_ID}",
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Preparar un puesto para una persona nueva",
"status": "Open"
},
"meta": {
"customId": "ERP-WORKTASK-2026-0042",
"etag": "{CURRENT_ETAG}"
}
},
"meta": {
"requestId": "{REQUEST_ID}",
"etag": "{CURRENT_ETAG}"
}
}Tareas - actualizar con ETag e If-Match
Antes de modificar un registro, lea su versión actual y conserve el valor exacto del ETag, incluidas las comillas si forman parte del valor:
ETAG=$(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/worktasks/$WORKTASK_ID?fields=customId,title,status,priority,description" | jq -r '.data.meta.etag // .meta.etag')PATCH cambia únicamente los atributos seleccionados. Guarde el nuevo ETag cuando la operación termine correctamente:
curl --fail-with-body --silent --show-error --request PATCH --header "Accept: application/json, application/problem+json" --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $ETAG" --header "Idempotency-Key: erp-worktask-update-2026-0042" --data-raw '{
"attributes": {
"title": "Configurar el puesto para una persona nueva",
"status": "In progress",
"priority": "Normal",
"description": "Se están configurando el ordenador y el acceso a la red."
}
}' "$BASE_URL/api/v1/worktasks/$WORKTASK_ID" | jqNo utilice un ETag guardado antes de otra modificación. Cada mutación correcta puede cambiar la versión del registro.
Tareas - ETag antiguo o ausente
Si otra persona o integración ha cambiado la tarea, un ETag antiguo termina con 412 Precondition Failed y el código if_match_failed. La API no debe aplicar el cambio rechazado.
{
"type": "https://docs.codenica.com/errors/if_match_failed",
"title": "Precondition failed.",
"status": 412,
"detail": "El ETag proporcionado no es la versión actual de la tarea.",
"code": "if_match_failed",
"requestId": "{REQUEST_ID}"
}PATCH, DELETE, las relaciones, los archivos y el fijado sin el If-Match requerido devuelven 428 Precondition Required con el código if_match_required. Después de un 412, lea de nuevo el registro, decida si debe conservar el cambio local y solo entonces envíe una solicitud nueva.
Tareas - fijar y desfijar
El campo pin es de solo lectura dentro de attributes. Cámbielo mediante el endpoint específico:
POST /api/v1/worktasks/{WORKTASK_ID}/pinFijar en el nivel 3:
curl --fail-with-body --silent --show-error --request POST --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $ETAG" --header "Idempotency-Key: erp-worktask-pin-2026-0042" --data '{"pin":3}' "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/pin" | jqEl valor null desfija la tarea:
curl --fail-with-body --silent --show-error --request POST --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $NEW_ETAG" --header "Idempotency-Key: erp-worktask-unpin-2026-0042" --data '{"pin":null}' "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/pin" | jqLea de nuevo la tarea después de cualquiera de las dos operaciones, porque su ETag puede cambiar.
Tareas - relaciones de usuario: autor y agente
La relación de usuario tiene su propia ruta y sirve para leer el autor de la tarea y el agente asignado:
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/worktasks/$WORKTASK_ID/user-relationships?page=1&pageSize=20" | jqLa colección contiene únicamente relaciones con el tipo author o agent. Ejemplo de un elemento:
{
"targetId": "{USER_ID}",
"targetDataSet": "users",
"relationshipType": "agent",
"displayName": "Ana García",
"email": "[email protected]",
"role": "Agent"
}authorId y agentId son campos técnicos. No intente cambiarlos mediante un PATCH attributes normal. Si la versión de la API ofrece una acción de asignación independiente, siga su esquema y el scope requerido.
Tareas - relaciones de objetos permitidas
El esquema de tareas expone once grupos de objetos que pueden ser destinos de relaciones:
En assets, el tipo depende del asset concreto. La tabla utiliza computer como ejemplo; lea el itemType real del objeto seleccionado antes de guardar la relación.
Tareas - elegir targetItemType y formato de relación
targetItemType debe coincidir con el tipo real del objeto de destino. El orden más seguro es: leer la lista o el esquema del destino, leer su itemType y solo después construir el body de la relació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/assets?page=1&pageSize=10&sort=dateCreated&direction=desc" | jq '.data.items[0] | {id, itemType}'Las relaciones de objetos de una tarea no aceptan relationshipType. Envíe únicamente el identificador, el nombre de la colección y el tipo del objeto:
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer"
}No copie asset, document o task sin comprobar el destino concreto. Un tipo incorrecto produce un error de validación.
Tareas - añadir, leer y eliminar una relación
Para añadir una relación con un asset se necesita el ETag actual de la tarea y una Idempotency-Key independiente:
curl --fail-with-body --silent --show-error --request POST --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $ETAG" --header "Idempotency-Key: erp-worktask-relation-assets-2026-0042" --data '{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer"
}' "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships" | jqLea la relación con un filtro por conjunto de destino:
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/worktasks/$WORKTASK_ID/relationships?targetDataSet=assets&page=1&pageSize=100" | jqEliminar una relación:
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: $ETAG" --header "Idempotency-Key: erp-worktask-relation-delete-assets-2026-0042" "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships/assets/{ASSET_ID}" | jqDespués de eliminarla, la respuesta debe contener data=true. Añadir una relación nueva devuelve 201 Created; en algunas situaciones, volver a indicar una relación existente puede devolver 200 OK.
Tareas - lote de relaciones
Puede añadir o eliminar varias relaciones en una sola solicitud:
{
"add": [
{
"targetId": "{DOCUMENT_ID}",
"targetDataSet": "documents",
"targetItemType": "document"
}
],
"remove": [
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer"
}
]
}curl --fail-with-body --silent --show-error --request POST --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $ETAG" --header "Idempotency-Key: erp-worktask-relationships-batch-2026-0042" --data-binary @worktask-relationships.json "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships:batch" | jq{
"data": {
"added": 1,
"removed": 1,
"skipped": 0
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}Los lotes de relaciones tampoco aceptan relationshipType. Use el ETag actual de la tarea y lea el límite de elementos en el context. Guarde el nuevo ETag si se devuelve y, después, lea la colección para comprobar el resultado.
Tareas - lista de archivos y carga
Los archivos asignados a una tarea utilizan un grupo de endpoints separado. Empiece leyendo la lista:
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/worktasks/$WORKTASK_ID/files?page=1&pageSize=100" | jqUn elemento de la lista incluye id, fileName, contentType, size, relationshipType, isMain y downloadUrl. Cargue un archivo nuevo como multipart/form-data:
curl --fail-with-body --silent --show-error --request POST --header "Accept: application/json, application/problem+json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $ETAG" --header "Idempotency-Key: erp-worktask-file-upload-2026-0042" --form "file=@./workstation-instructions.pdf;type=application/pdf" "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files?relationshipType=instruction" | jqLa carga requiere worktasks:files:write, el ETag actual y el límite de archivo leído en el context. Para las tareas, la API establece isMain=false; no dé por hecho que existe una operación separada para designar un archivo principal.
Tareas - descargar y adjuntar un archivo
Descargue el contenido mediante la ruta content y guárdelo en modo binario:
curl --fail-with-body --silent --show-error --output ./workstation-instructions-downloaded.pdf --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files/{FILE_ID}/content"Si un archivo ya está guardado en el sistema, adjúntelo a una segunda tarea sin volver a cargar su contenido. Lea antes el ETag de la segunda tarea:
curl --fail-with-body --silent --show-error --request POST --header "Accept: application/json, application/problem+json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "If-Match: $SECOND_WORKTASK_ETAG" --header "Idempotency-Key: erp-worktask-file-attach-2026-0042" "$BASE_URL/api/v1/worktasks/$SECOND_WORKTASK_ID/files/{FILE_ID}?relationshipType=reference" | jqAttach crea una relación de archivo con la segunda tarea. El mismo archivo puede ser visible en los dos registros y reference es el tipo de relación del archivo, no el tipo de una relación entre objetos.
Tareas - desvincular y eliminar un archivo
Desvincule el archivo de la segunda tarea utilizando su ETag actual:
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: $SECOND_WORKTASK_ETAG" --header "Idempotency-Key: erp-worktask-file-detach-2026-0042" "$BASE_URL/api/v1/worktasks/$SECOND_WORKTASK_ID/files/{FILE_ID}" | jqLa desvinculación debe devolver data=true y no debe eliminar la relación del archivo con la tarea de origen. Para eliminar el archivo de la tarea de origen, lea su nuevo ETag y ejecute:
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: $SOURCE_WORKTASK_ETAG" --header "Idempotency-Key: erp-worktask-file-delete-2026-0042" "$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files/{FILE_ID}" | jqCompruebe la lista de archivos después de eliminarlo. Las tareas no tienen un endpoint separado para establecer un archivo principal.
Tareas - operaciones batch para registros
El endpoint /api/v1/worktasks:batch combina la creación, actualización y eliminación de tareas. Cada elemento de actualización o eliminación tiene su propio ETag:
{
"items": [
{
"operation": "create",
"create": {
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-BATCH-A",
"title": "Preparar acceso",
"status": "Open",
"priority": "Normal",
"category": "IT"
}
}
},
{
"operation": "update",
"id": "{WORKTASK_ID}",
"ifMatch": "{CURRENT_ETAG}",
"update": {
"attributes": {
"title": "Preparar acceso - segunda fase",
"status": "In progress"
}
}
},
{
"operation": "delete",
"id": "{OTHER_WORKTASK_ID}",
"ifMatch": "{OTHER_CURRENT_ETAG}"
}
]
}curl --fail-with-body --silent --show-error --request POST --header "Content-Type: application/json" --header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" --header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" --header "Idempotency-Key: erp-worktasks-batch-2026-0042" --data-binary @worktasks-batch.json "$BASE_URL/api/v1/worktasks:batch" | jq{
"data": {
"items": [
{
"index": 0,
"operation": "create",
"status": 201,
"id": "{CREATED_WORKTASK_ID}",
"data": {
"meta": {
"etag": "{CREATED_ETAG}"
}
}
}
],
"succeeded": 1,
"failed": 0
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}En un resultado parcial, la API puede devolver 207 Multi-Status. Recorra data.items, revise cada elemento y repita solo las operaciones que realmente necesiten otro intento.
Tareas - eliminar un registro
Antes de eliminarlo, lea de nuevo el registro, compruebe su UUID y su ETag actual y use una Idempotency-Key nueva:
curl --fail-with-body --silent --show-error --request DELETE --header "Accept: application/json, application/problem+json" --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-worktask-delete-2026-0042" "$BASE_URL/api/v1/worktasks/$WORKTASK_ID" | jqUna respuesta correcta contiene 200 OK y data=true. Después de eliminarlo, compruebe que el registro 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/worktasks/$WORKTASK_ID"El estado esperado es 404 Not Found. También puede filtrar la lista con customId=ERP-WORKTASK-2026-0042 y confirmar totalItems=0.
Tareas - errores, límites y orden seguro de operaciones
Las respuestas de error utilizan el formato Problem Details. Use code en la lógica de integración y conserve también requestId al informar de un problema. No escriba el Secret ni los headers completos en los logs.
validation_failedauthentication_requiredworktask_not_foundfile_not_foundif_match_failedfile_too_largeif_match_requiredidempotency_key_requiredinternal_errorLea los headers X-RateLimit-Limit y X-RateLimit-Remaining. En un 429, lea Retry-After y aplique backoff con esperas crecientes y jitter. Limite el número de intentos y no repita indefinidamente los errores 400, 401, 403, 404 o 412.
Orden seguro de operaciones
- Establezca
BASE_URLpara la instalación correcta y lea elcontext. - Compruebe scopes, límites, esquema y el
itemTypereal de los destinos de relaciones. - Cree una tarea con su propia
Idempotency-Keyy guarde la UUID y el ETag. - Lea el ETag actual antes de cada modificación, relación, operación de archivo o acción de fijado.
- Guarde el nuevo ETag después de una mutación correcta y compruebe el resultado mediante una lectura.
- Después de sincronizar, compruebe el registro por
customIdy elimine los datos de demostración con una solicitud independiente. - En n8n, use el nodo HTTP Request. Guarde Client ID y Client Secret en las credenciales y pase la UUID, el ETag y la Idempotency-Key entre los nodos.
