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/worktasks

BASE_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.

Licencia
Acceso a Codenica API
Número máximo de claves
Starter
No
0
Plus
50
Enterprise
100

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/json

Ejemplo 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" | jq

Compruebe 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.

Campo
Tipo
Uso
customId
string
Identificador asignado por el sistema que realiza la integración.
dateDue
date-time
Fecha límite de la tarea.
dateEnd
date-time
Fecha en la que se terminó el trabajo.
location
string
Lugar donde se realiza el trabajo.
department
string
Departamento o unidad responsable.
tag
string
Etiquetas, máximo 2000 caracteres.
link
string
Enlace a la fuente o a los detalles de otra aplicación.
title
string
Título breve de la tarea.
status
string
Estado del proceso.
priority
string
Prioridad.
category
string
Categoría de la tarea.
description
string
Descripción, máximo 10000 caracteres.

El 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.

Método
Ruta
Uso
GET
/api/v1/worktasks
Lista, paginación y filtros.
POST
/api/v1/worktasks
Crear una tarea.
GET
/api/v1/worktasks/schema
Esquema de campos y relaciones.
GET
/api/v1/worktasks/stats
Estadísticas de campos.
GET
/api/v1/worktasks/values
Valores de campos con búsqueda.
GET
/api/v1/worktasks/{id}
Leer una tarea.
PATCH
/api/v1/worktasks/{id}
Actualización parcial.
DELETE
/api/v1/worktasks/{id}
Eliminar una tarea.
POST
/api/v1/worktasks:batch
Crear, actualizar y eliminar en una solicitud.
GET/POST
/api/v1/worktasks/{id}/relationships
Leer o añadir relaciones con objetos.
POST
/api/v1/worktasks/{id}/relationships:batch
Añadir y eliminar varias relaciones.
GET
/api/v1/worktasks/{id}/user-relationships
Leer el autor y el agente.
GET/POST/DELETE
/api/v1/worktasks/{id}/files...
Listar, subir, adjuntar, desvincular y descargar archivos.
POST
/api/v1/worktasks/{id}/pin
Fijar o desfijar una tarea.

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" | jq

Lea 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" | jq

Un 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:00Z

Las 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" | jq

Use 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" | jq

Los 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" | jq

Ambas 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" | jq

Una 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" | jq

Tareas - 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" | jq

Un 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" | jq

No 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}/pin

Fijar 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" | jq

El 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" | jq

Lea 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" | jq

La 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:

Conjunto de destino
Ejemplo de itemType
Finalidad
assets
computer
Asset, por ejemplo un ordenador o dispositivo.
clients
client
Cliente.
vendors
vendor
Proveedor.
documents
document
Documento.
tickets
ticket
Ticket.
changes
change
Cambio.
problems
problem
Problema.
releases
release
Versión.
notes
note
Nota.
approvals
approval
Aprobación.
requesteditems
requesteditem
Elemento solicitado.

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" | jq

Lea 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" | jq

Eliminar 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}" | jq

Despué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" | jq

Un 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" | jq

La 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" | jq

Attach 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}" | jq

La 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}" | jq

Compruebe 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" | jq

Una 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.

HTTP
Código o situación
Respuesta
400
validation_failed
Corrija el body, el campo, el filtro o el destino. No repita la solicitud sin cambiar los datos.
401
authentication_required
Compruebe los dos headers, el estado de la clave y la dirección de la instalación.
403
Falta un scope o acceso
Añada el scope mínimo que falta o cambie la operación.
404
worktask_not_found
Compruebe la UUID, la dirección de la base de datos y la visibilidad.
404
file_not_found
Lea la lista actual de archivos.
409
Conflicto
Lea el estado actual y decida si la operación se puede repetir con seguridad.
412
if_match_failed
Lea el ETag actual y no sobrescriba los cambios automáticamente.
413
file_too_large
Compruebe el límite en context y reduzca el archivo.
428
if_match_required
Envíe el If-Match actual al modificar un registro existente.
428
idempotency_key_required
Añada una Idempotency-Key única a la mutación.
429
Límite de solicitudes superado
Lea Retry-After y aplique backoff.
500
internal_error
Conserve requestId, limite los reintentos e informe del problema.
207
Resultado batch parcial
Compruebe cada elemento por separado.

Lea 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

  1. Establezca BASE_URL para la instalación correcta y lea el context.
  2. Compruebe scopes, límites, esquema y el itemType real de los destinos de relaciones.
  3. Cree una tarea con su propia Idempotency-Key y guarde la UUID y el ETag.
  4. Lea el ETag actual antes de cada modificación, relación, operación de archivo o acción de fijado.
  5. Guarde el nuevo ETag después de una mutación correcta y compruebe el resultado mediante una lectura.
  6. Después de sincronizar, compruebe el registro por customId y elimine los datos de demostración con una solicitud independiente.
  7. 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.