Soluciones en la API de Codenica
Empiece a trabajar con las soluciones mediante la API de Codenica creando una clave en los ajustes de Codenica. Si todavía no tiene una clave, abra en una pestaña nueva el artículo API de Codenica - introducción. Allí se explican las reglas comunes para emitir claves, guardar el secreto y autenticar las solicitudes.
El nombre técnico del módulo es solutions y el tipo de cada objeto es solution. Una solución es una entrada de la base de conocimientos. Puede contener instrucciones, una descripción del procedimiento, referencias y archivos de apoyo. No es un objeto de flujo de trabajo como una Incidencia, un Cambio, un Problema o una Versión. Por eso, no copie en una solución sus campos de estado, prioridad o escalado.
En las secciones siguientes encontrará la dirección, los scopes, el contexto, el esquema, los campos, las listas, los filtros, la creación, la idempotencia, el ETag, la edición, las operaciones por lotes, las relaciones con Problemas, los datos del autor y del editor, los archivos, las valoraciones y la eliminación.
Los ejemplos utilizan el prefijo PUBLIC-API-SOLUTION-20260905134845. Sustitúyalo en su integración por un identificador propio y adapte las direcciones de correo, los identificadores y los valores de los campos a los datos de su base de datos.
Soluciones - dirección de la API y tipo de instalación
Todas las rutas de Soluciones comienzan por:
{BASE_URL}/api/v1/solutionsBASE_URL es la dirección del servidor Codenica sin el tramo final /api/v1. En Codenica Cloud, utilice el dominio público asignado a la empresa correspondiente:
export BASE_URL="https://su-empresa.codenica.com"En una instalación On-Premise predeterminada, Codenica Discovery registra localmente esta dirección:
export BASE_URL="http://codenica.local:5150"Si el administrador ha publicado la instalación bajo un dominio de la empresa, mediante un proxy inverso, con HTTPS o en otro puerto, utilice exactamente la dirección que le haya proporcionado:
export BASE_URL="https://api.su-empresa.example"No utilice localhost si el programa que integra la API se ejecuta en un equipo distinto. La base de datos correcta se selecciona a partir de la dirección utilizada por la integración. No envíe tenantId en el body ni en la cadena de consulta.
Soluciones - clave de API y límites de licencia
Cree una clave de API en Codenica desde Ajustes - API - API Keys. El secreto se muestra una sola vez, inmediatamente después de crear o rotar la clave. En ese momento, guarde Client ID y Client Secret en el almacenamiento seguro que utilice la integración.
La API de Codenica está disponible con las licencias Plus y Enterprise. Plus permite hasta 50 claves activas y Enterprise hasta 100. Starter no incluye la API de Codenica. Cree una clave independiente para cada aplicación y entorno, de modo que pueda administrar sus scopes, rotar el secreto o retirar el acceso sin afectar a las demás integraciones.
Al eliminar una clave, se borra su registro y se libera un lugar dentro del límite. Cuando pasa la fecha de caducidad, la clave deja de autenticar solicitudes, pero permanece en la lista hasta que se elimina. Si no establece una fecha final al crearla, la validez predeterminada es de 90 días. La validez máxima de una clave es de 5 años.
Soluciones - autenticación y solicitudes seguras
Autentique cada solicitud de la API de Codenica con las dos cabeceras de la clave:
export CLIENT_ID="cna_su_client_id"
export CLIENT_SECRET="cns_su_client_secret"
curl --request GET --url "$BASE_URL/api/v1/solutions?page=1&pageSize=25" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Una integración externa no necesita el JWT del administrador ni las cookies del panel de Codenica. No incluya la clave en un repositorio, en código enviado al navegador, en una URL, en el historial del shell ni en los registros. Fuera de las pruebas locales, utilice HTTPS.
Conserve meta.requestId de la respuesta. Sirve para localizar una solicitud concreta durante el diagnóstico, pero no sustituye al identificador de la solución y no debe tratarse como un secreto.
Soluciones - comprobación del contexto de conexión
Antes de realizar la primera escritura, lea el contexto. Así podrá comprobar que la dirección apunta a la base de datos correcta y que la clave elegida tiene los scopes necesarios:
curl --request GET --url "$BASE_URL/api/v1/context" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Compruebe en la respuesta:
data.apiVersionydata.contractVersion;data.tenant.id,data.tenant.nameydata.tenant.resolvedDomain;data.caller.authenticationcon el valorapi_key;- la presencia de
solutionsendata.capabilities.resources; - los scopes asignados a la clave;
- los límites de páginas, operaciones por lotes, archivos y solicitudes.
Si el contexto apunta a otra base de datos o no incluye un scope necesario, detenga la integración y corrija la dirección o la clave. Los scopes no se pueden añadir a una solicitud individual.
Soluciones - scopes y permisos
La gestión completa de Soluciones requiere scopes que correspondan a las operaciones que utilizará la integración:
solutions:read
solutions:write
solutions:delete
solutions:schema
solutions:stats
solutions:relationships:read
solutions:relationships:write
solutions:users:read
solutions:files:read
solutions:files:write
solutions:technical:read
solutions:technical:write
solutions:rating:write
problems:read
users:readPara las lecturas habituales basta con solutions:read. El esquema y las estadísticas requieren los scopes independientes solutions:schema y solutions:stats. Para leer relaciones, autores, editores y archivos se necesitan los scopes de lectura correspondientes. Las operaciones de escritura utilizan los scopes equivalentes con :write.
solutions:relationships:readysolutions:relationships:writecubren las relaciones de objetos con Problemas;solutions:users:readyusers:readcubren los datos de autores y editores, según la configuración;solutions:files:readysolutions:files:writecubren la consulta, la subida, la asociación y la eliminación de archivos;solutions:rating:writees necesario para enviar o retirar su propia valoración;- utilice los scopes técnicos únicamente cuando la integración necesite campos marcados como técnicos en el esquema.
El scope problems:read es necesario cuando la integración busca un Problema que utilizará como objetivo de una relación. El módulo de Soluciones no crea ni elimina ese Problema. Conceda únicamente los scopes que la integración necesite.
Soluciones - esquema y campos
El esquema muestra qué campos se pueden leer y escribir en la base de datos seleccionada. Consúltelo antes de crear un formulario o un mapeo de campos:
curl --request GET --url "$BASE_URL/api/v1/solutions/schema" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La respuesta incluye, entre otros datos, data.itemType, data.fields y data.relationshipTargets. El itemType fijo de este módulo es solution. Para cada campo, compruebe readable, writable, required, technical, unique y maxLength. No construya el mapeo únicamente a partir de los ejemplos de este artículo.
Soluciones - campos editables y campos del sistema
Al crear un registro debe proporcionar title y category. El catálogo público de campos de negocio incluye:
customId
title
description
location
department
type
tags
section
category
visibilityLongitudes máximas definidas por el esquema público:
customIdtitledescriptionlocationdepartmenttypetagssectioncategoryvisibilityLos siguientes valores son de solo lectura y no deben incluirse en un body normal de PATCH:
helpful
notHelpful
totalFiles
creator
updater
importId
importSource
dateImportedid y itemType forman parte de la envoltura del recurso. dateCreated y dateUpdated son datos del sistema. No intente modificarlos mediante attributes.
Soluciones - endpoints principales
Las rutas principales del módulo solutions son:
GET /api/v1/solutions
POST /api/v1/solutions
GET /api/v1/solutions/{SOLUTION_ID}
PATCH /api/v1/solutions/{SOLUTION_ID}
DELETE /api/v1/solutions/{SOLUTION_ID}
GET /api/v1/solutions/schema
GET /api/v1/solutions/stats
GET /api/v1/solutions/values
GET /api/v1/solutions/{SOLUTION_ID}/relationships
POST /api/v1/solutions/{SOLUTION_ID}/relationships
POST /api/v1/solutions/{SOLUTION_ID}/relationships:batch
GET /api/v1/solutions/{SOLUTION_ID}/user-relationships
GET /api/v1/solutions/{SOLUTION_ID}/files
POST /api/v1/solutions/{SOLUTION_ID}/files
GET /api/v1/solutions/{SOLUTION_ID}/files/{FILE_ID}/content
POST /api/v1/solutions/{SOLUTION_ID}/ratingTodas las rutas requieren autenticación. Las operaciones que modifican datos también requieren Idempotency-Key, mientras que las operaciones protegidas por versión requieren el If-Match actual. Consulte el esquema y la respuesta del contexto para conocer los requisitos exactos de la operación que va a realizar.
Soluciones - listas y paginación
La lista se devuelve por páginas. El siguiente ejemplo obtiene la primera página y ordena las soluciones por título:
curl --request GET --url "$BASE_URL/api/v1/solutions?itemType=solution&page=1&pageSize=25&sort=title&direction=asc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La respuesta incluye, entre otros valores:
data.items
data.page
data.pageSize
data.totalItems
data.totalPages
data.hasNextPageSolicite las páginas siguientes mientras data.hasNextPage sea true. No suponga que el número de registros de la primera página representa la lista completa. Ajuste pageSize al límite devuelto por el contexto en lugar de solicitar siempre el máximo.
Soluciones - búsqueda, filtros y ordenación
Puede filtrar, entre otros campos, por ids, customId, title, description, location, department, type, tags, section, category, visibility, helpful, notHelpful, createdAfter, createdBefore, updatedAfter y updatedBefore. Codifique en la URL los valores que contengan espacios, comas o caracteres especiales.
Ejemplo: listar las soluciones de la categoría Public API:
curl --request GET --url "$BASE_URL/api/v1/solutions?category=Public%20API&page=1&pageSize=25&sort=title&direction=asc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"El parámetro search busca en los datos textuales de la solución, incluidos el título, la descripción, el tipo, las etiquetas, la sección, la categoría, la visibilidad, la ubicación y el departamento:
curl --request GET --url "$BASE_URL/api/v1/solutions?search=backup&page=1&pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Ordene únicamente por un campo que exponga el esquema. No suponga que todos los campos visibles en el formulario se pueden utilizar como parámetro sort.
Soluciones - proyección de campos y datos incluidos
Si la integración necesita solo una parte del registro, limite la respuesta mediante fields:
curl --request GET --url "$BASE_URL/api/v1/solutions?customId=PUBLIC-API-SOLUTION-20260905134845-SOURCE&fields=title%2Ccategory%2Cvisibility&page=1&pageSize=10" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Puede obtener un registro junto con sus archivos, relaciones y datos del autor o del editor:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}?fields=title%2Ccategory%2Cdescription%2Cvisibility&include=files%2Crelationships%2Cusers" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Los valores permitidos para include son files, relationships y users. Cada uno requiere el scope correspondiente. fields=* solicita todos los campos disponibles, pero los campos técnicos solo aparecen cuando se concede el scope técnico adecuado.
Soluciones - estadísticas y valores de campos
Utilice las estadísticas para contar registros y agruparlos por un campo:
curl --request GET --url "$BASE_URL/api/v1/solutions/stats?field=category&limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La respuesta incluye, entre otros datos, total, field y una matriz values. El valor category=Public API puede servir como filtro práctico para los datos de demostración.
Para obtener los valores distintos de un campo, utilice la ruta values:
curl --request GET --url "$BASE_URL/api/v1/solutions/values?field=visibility&search=internal&limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"limit debe estar dentro del intervalo admitido por la API. El intervalo actual para estos endpoints es de 1 a 500. Las solicitudes de estadísticas y valores son de solo lectura y no modifican las soluciones.
Soluciones - crear un registro
Al crear un registro, incluya el tipo técnico solution en el body y los campos editables dentro de attributes. El payload mínimo requiere title y category:
{
"itemType": "solution",
"attributes": {
"customId": "PUBLIC-API-SOLUTION-20260905134845-SOURCE",
"title": "PUBLIC-API-SOLUTION-20260905134845 integration knowledge article",
"description": "Created through the Codenica Public API Solutions flow.",
"location": "Warsaw",
"department": "IT",
"type": "How-to",
"tags": "public-api,solution,integration",
"section": "Integrations",
"category": "Public API",
"visibility": "team"
}
}Guarde el contenido como solution-create.json y envíelo:
curl --request POST --url "$BASE_URL/api/v1/solutions" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-solution-create-20260905134845" \
--data-binary @solution-create.jsonUna creación correcta devuelve 201 Created. La respuesta contiene el UUID de la solución, data.itemType=solution, los atributos guardados, las fechas del sistema y data.meta.etag. En la mayoría de las integraciones, deje que el sistema asigne el id.
Soluciones - repetir la creación de forma segura
Si el resultado de una solicitud es incierto, repita exactamente el mismo payload con la misma Idempotency-Key. Así evitará que la integración cree una segunda solución:
curl --request POST --url "$BASE_URL/api/v1/solutions" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-solution-create-20260905134845" \
--data-binary @solution-create.jsonUtilice la misma clave únicamente para la misma intención y el mismo body. Genere una clave nueva para una nueva solución o un nuevo payload. Después de un timeout, no cambie la clave antes de comprobar si la primera escritura terminó en el servidor.
Soluciones - leer un registro y su ETag
Después de crear o localizar una solución, obtenga el registro individual y guarde el ETag devuelto en la cabecera HTTP y en data.meta.etag:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}?fields=title%2Ccategory%2Cdescription%2Cvisibility%2Ctags" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Una respuesta correcta devuelve 200 OK y una cabecera ETag:
ETag: "..."
data.meta.etag: "..."
meta.etag: "..."Utilice el valor actual para la siguiente actualización, modificación de relación, operación de archivo, valoración o eliminación. El ETag representa la versión de toda la solución, por lo que un cambio en sus atributos, relaciones o archivos puede invalidar el valor anterior.
Soluciones - actualización parcial con If-Match
Actualice únicamente los campos que deban cambiar. La siguiente solicitud modifica la descripción y la visibilidad:
{
"attributes": {
"description": "Updated through the Solutions Public API flow.",
"visibility": "internal",
"tags": "public-api,solution,updated",
"section": "Updated integrations"
}
}curl --request PATCH --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-update-20260905134845" \
--data-binary @solution-update.jsonUna actualización correcta devuelve 200 OK, el UUID sin cambios y un ETag nuevo tanto en la cabecera de respuesta como en los metadatos. Guarde el nuevo valor antes de realizar otra mutación.
Soluciones - ETag obsoleto y ausencia de If-Match
La API evita que una solución sobrescriba una versión más reciente. Un ETag antiguo se rechaza:
Si dos procesos leen la misma solución y uno guarda primero, el segundo tiene un ETag obsoleto. El intento de escribir con ese valor se rechaza:
HTTP 412 Precondition Failed
code: if_match_failedDespués de HTTP 412, vuelva a leer el registro, decida cómo combinar los cambios y envíe solo entonces un nuevo PATCH. Una solicitud rechazada por un ETag obsoleto no debe modificar los datos.
Una mutación sin la cabecera requerida devuelve:
HTTP 428 Precondition Required
code: if_match_requiredNo intente eludir este requisito enviando un valor vacío. Lea primero el registro actual y utilice su ETag exacto.
Soluciones - operaciones por lotes
Utilice POST /api/v1/solutions:batch cuando deba crear, actualizar o eliminar varias soluciones en un único conjunto enviado. Cada elemento declara su operación:
{
"items": [
{
"operation": "create",
"create": {
"itemType": "solution",
"attributes": {
"customId": "PUBLIC-API-SOLUTION-BATCH-A",
"title": "Batch Solution A",
"category": "Public API",
"description": "Batch-created Solution A",
"type": "How-to",
"visibility": "team"
}
}
},
{
"operation": "create",
"create": {
"itemType": "solution",
"attributes": {
"customId": "PUBLIC-API-SOLUTION-BATCH-B",
"title": "Batch Solution B",
"category": "Public API",
"description": "Batch-created Solution B",
"type": "Reference",
"visibility": "team"
}
}
}
]
}curl --request POST --url "$BASE_URL/api/v1/solutions:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-solution-batch-create-20260905134845" \
--data-binary @solutions-batch.jsonPara una actualización, el elemento contiene operation=update, id, ifMatch y update.attributes:
{
"items": [
{
"operation": "update",
"id": "{SOLUTION_A_ID}",
"ifMatch": "{SOLUTION_A_ETAG}",
"update": {
"attributes": {
"description": "Batch update A"
}
}
}
]
}Para una eliminación, el elemento contiene operation=delete, id y el ifMatch actual. La respuesta puede incluir succeeded y failed. Un resultado parcial también puede utilizar HTTP 207 Multi-Status. Compruebe cada elemento por separado. Un batch no es una transacción.
Soluciones - relaciones únicamente con Problemas
Las Soluciones admiten relaciones de objetos únicamente con el módulo Problemas. Un objetivo habitual devuelto por el esquema es:
targetDataSet: problems
targetItemType: problemNo suponga que una solución se puede conectar mediante estos endpoints con un Recurso, un Documento, un Cliente, un Proveedor, una Incidencia, un Cambio o una Versión. Si el esquema de una base de datos concreta no devuelve el objetivo, la integración no debe utilizarlo.
Primero busque un Problema que se pueda leer mediante un campo de ordenación público:
curl --request GET --url "$BASE_URL/api/v1/problems?itemType=problem&page=1&pageSize=10&sort=subject&direction=asc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"En el flujo de demostración se utilizó el Problema con el identificador 9793181f-a225-4928-8062-80d6e69cb792. Su integración debe buscar el objetivo actual y no tratar este UUID como una constante.
Soluciones - añadir, leer y eliminar relaciones
El body para añadir directamente una relación puede tener este formato:
{
"targetId": "9793181f-a225-4928-8062-80d6e69cb792",
"targetDataSet": "problems",
"targetItemType": "problem",
"relationshipType": "related"
}Antes de cada mutación, obtenga el ETag actual de la solución:
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/relationships" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-problem-relation-add-20260905135119" \
--data-binary @solution-problem-relation.jsonUna adición correcta devuelve 201 Created. Lea la relación mediante una ruta independiente:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/relationships?targetDataSet=problems&targetItemType=problem&page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"La eliminación directa requiere el ETag actual y el identificador del objetivo:
curl --request DELETE --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/relationships/problems/9793181f-a225-4928-8062-80d6e69cb792?relationshipType=related" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-problem-relation-delete-20260905135119"La respuesta de eliminación devuelve 200 y data=true. Después de la operación, vuelva a leer la colección.
Soluciones - relaciones por lotes con Problemas
Para añadir y eliminar relaciones al mismo tiempo, utilice la ruta relationships:batch:
{
"add": [
{
"targetId": "9793181f-a225-4928-8062-80d6e69cb792",
"targetDataSet": "problems",
"targetItemType": "problem",
"relationshipType": "related"
}
],
"remove": []
}curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/relationships:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-problem-relation-batch-add-20260905135119" \
--data-binary @solution-problem-relation-batch.jsonPara eliminar una relación mediante un batch, deje add vacío y coloque el elemento en remove:
{
"add": [],
"remove": [
{
"targetId": "9793181f-a225-4928-8062-80d6e69cb792",
"targetDataSet": "problems",
"targetItemType": "problem",
"relationshipType": "related"
}
]
}La respuesta contiene los contadores added, removed y skipped. Después de añadir, compruebe added=1 y después de eliminar, removed=1. Antes de cada nueva escritura, utilice un ETag reciente.
Soluciones - relaciones de autores y editores
En este módulo, las relaciones de usuarios son metadatos sobre la autoría y la última edición. Los tipos permitidos son author y editor:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/user-relationships?page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Un elemento de ejemplo puede contener:
{
"targetId": "8e9cbff3-340f-41f6-97ec-6997bb915829",
"targetDataSet": "users",
"relationshipType": "author",
"displayName": "Fred Savage",
"email": "[email protected]",
"role": "Administrator"
}Las relaciones author y editor se leen de los campos de autor y editor de la solución. El módulo público de Soluciones no ofrece endpoints para añadirlas, modificarlas o eliminarlas. No intente crear los tipos agent, watcher, appUserRequester o clientRequester, ya que pertenecen a otros objetos.
Soluciones - archivos
Antes de cualquier operación de archivos, lea la solución actual y su ETag. Lista de archivos:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/files?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Cada elemento de la lista incluye, entre otros datos, id, name, fileName, contentType, size, width, height, relationshipType, isMain y downloadUrl. En Soluciones, isMain siempre es false. El módulo no ofrece un endpoint set-main, por lo que no debe intentar establecer un archivo principal.
El envío de un archivo requiere el formato multipart/form-data:
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/files?relationshipType=documentation" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-file-20260905134845" \
--form "[email protected];type=text/plain"Una subida correcta devuelve 201 Created y el recurso del archivo. En el ejemplo se utiliza solution-one.txt con el tipo text/plain. La subida cambia la versión de la solución, así que después debe obtener un ETag nuevo.
Descargue el contenido mediante una ruta autenticada:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/files/{FILE_ID}/content" \
--header "Accept: application/octet-stream" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output solution-one-downloaded.txtTrate downloadUrl como una ruta de la API, no como un enlace público anónimo. Si el archivo ya existe en el mismo espacio de archivos, puede asociarlo a otra solución:
curl --request POST --url "$BASE_URL/api/v1/solutions/{TARGET_SOLUTION_ID}/files/{FILE_ID}?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TARGET_CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-file-attach-20260905134845"Al asociarlo, utilice el ETag de la solución de destino, no el del registro del que procede el archivo. Para eliminar un archivo se requiere el ETag actual:
curl --request DELETE --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/files/{FILE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-file-delete-20260905134845"Después de recibir 200, vuelva a leer la lista de archivos para confirmar que el archivo ya no se devuelve.
Soluciones - valoración de utilidad
La valoración es una mutación independiente. Puede marcar una solución como útil, como no útil o retirar su propia valoración:
{
"rating": 1
}1- útil;0- no útil;-1- retirar su propia valoración.
Marcar como útil:
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-rating-helpful-20260905134845" \
--data '{"rating":1}'Retirar su propia valoración:
curl --request POST --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $RATING_CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-rating-reset-20260905134845" \
--data '{"rating":-1}'Ambas operaciones requieren un ETag. La respuesta contiene los contadores actuales helpful y notHelpful y un ETag nuevo. No actualice helpful ni notHelpful mediante un PATCH normal.
Soluciones - eliminar un registro
La eliminación no se puede deshacer. Por eso, lea primero el registro y obtenga el ETag actual:
curl --request DELETE --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: public-api-solution-delete-20260905134845"La respuesta correcta es 200 con data=true. Después, realice un GET de comprobación y consulte una lista filtrada:
curl --request GET --url "$BASE_URL/api/v1/solutions/{SOLUTION_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request GET --url "$BASE_URL/api/v1/solutions?customId=PUBLIC-API-SOLUTION-20260905134845-SOURCE&page=1&pageSize=10" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Después de eliminarlo, el GET individual devuelve 404 Not Found con el código solution_not_found. La lista filtrada por customId debe tener totalItems=0. Conviene comprobar o limpiar antes las relaciones y los archivos mediante la integración.
Soluciones - errores, límites y seguridad
Los errores de la API utilizan el formato Problem Details. Los campos principales son status, code, detail y requestId:
{
"type": "https://docs.codenica.com/errors/if_match_failed",
"title": "Precondition failed.",
"status": 412,
"detail": "The supplied ETag is not the current solution version.",
"instance": "/api/v1/solutions/{SOLUTION_ID}",
"code": "if_match_failed",
"requestId": "..."
}code y detailLea las cabeceras X-RateLimit-Limit y X-RateLimit-Remaining. Después de un 429, respete Retry-After cuando se devuelva y aplique reintentos controlados con un retraso cada vez mayor.
Las soluciones pueden contener información operativa e instrucciones internas. Reduzca la selección de campos, utilice HTTPS y limite la clave a la base de datos concreta. Guarde Client ID y Client Secret fuera del código fuente, no los escriba en los registros ni los envíe en incidencias.
Soluciones - orden recomendado para la integración
- Determine la dirección real de Cloud u On-Premise y establezca
BASE_URL. - Cree una clave independiente para la aplicación y el entorno desde Ajustes - API - API Keys.
- Conceda únicamente los scopes necesarios para leer, escribir, gestionar relaciones, archivos o valoraciones.
- Envíe
GET /api/v1/contexty compruebe la base de datos, el caller, los scopes y los límites. - Obtenga
GET /api/v1/solutions/schemay cree el mapeo de campos. - Obtenga la lista o busque una solución existente.
- Cree el registro mediante
POSTcon unIdempotency-Keyúnico. - Guarde el UUID y el ETag de la respuesta.
- Actualice el ETag antes de cada modificación, relación, operación de archivos, valoración o eliminación.
- Cree relaciones de objetos únicamente con un Problema devuelto por el esquema.
- Lea las relaciones de autores y editores, ya que no tienen endpoints públicos de escritura.
- Después de cada mutación, lea el resultado y guarde el ETag nuevo.
- Ante un
412, vuelva a leer el registro, resuelva el conflicto y solo después repita la operación. - En las operaciones por lotes, compruebe cada resultado porque un error parcial no revierte los elementos que sí tuvieron éxito.
- Antes de eliminar, confirme el ETag actual y después compruebe el HTTP
404y una lista vacía filtrada porcustomId.
Este flujo permite sincronizar las soluciones de la base de conocimientos con otro sistema sin basar la integración en suposiciones sobre campos, relaciones o datos del sistema.
