Generación de issues dentro de modelos 3D con APS: entendiendo los pushpins del visor de Autodesk
Cuando alguien intenta crear issues dentro de un modelo 3D mediante la API de Autodesk Platform Services, lo normal es que empiece buscando en el sitio equivocado, y acabe pensando que es algo imposible de hacer.
Tiene sentido. Si lo que quieres crear es un issue, lo lógico parece buscar la API de issues. Hasta ahí, todo razonable. El problema es que, cuando hablamos de crear issues visibles dentro del visor de Autodesk Forma, no estamos hablando realmente de issues.
Estamos hablando de pushpins. Y ese matiz cambia bastante la forma de entender el problema.
La documentación de Autodesk tampoco ayuda demasiado. El ecosistema de Autodesk Construction Cloud ya se ha renombrado a Forma, pero muchas APIs, tutoriales y referencias siguen viviendo en documentación heredada de BIM 360. En algunos casos, la información está repartida entre Viewer, Issues, Model Coordination, RFIs y tutoriales antiguos.
El resultado es que muchos desarrolladores buscan “crear un issue en el modelo” y acaban mezclando conceptos que Autodesk separa internamente:
- un issue como objeto de gestión,
- un pushpin como marcador visual,
- un viewerState como contexto de cámara,
- un linkedDocument como vínculo con el modelo o plano,
- y un endpoint específico de Model Coordination cuando el issue nace de un flujo de coordinación visual.
Con este artículo pretendemos ordenar todo eso.
No vamos a hablar de issues en abstracto. Vamos a hablar de cómo se generan incidencias localizadas dentro de modelos 3D en el visor de Autodesk, qué papel tienen los pushpins y qué parámetros hay que entender antes de empezar a enviar payloads a la API como si el servidor te debiera dinero.
Tabla de contenidos
El error inicial: pensar que dentro del visor solo hay issues
En la interfaz de BIM 360 o ACC, el usuario ve un marcador dentro del modelo y lo interpreta como un issue.
Y no está del todo mal.
Desde el punto de vista del usuario, ese icono representa una incidencia: algo que revisar, corregir, asignar o cerrar. Tiene un título, un estado, un responsable, comentarios y una trazabilidad.
Pero desde el punto de vista técnico, ese icono no es el issue completo.
Ese icono es el pushpin.
El pushpin es el marcador espacial que permite ubicar una incidencia en un punto concreto del modelo o del plano. Es la parte visual y geométrica del problema. Es lo que permite decir: “este issue está aquí, en este elemento, desde esta vista y con esta cámara”.
El issue, en cambio, es el objeto de gestión. Es lo que tiene estado, asignación, descripción, fechas, tipo, subtipo, comentarios, adjuntos y todo ese maravilloso aparato burocrático sin el cual la industria AECO se sentiría peligrosamente viva.
Por eso conviene separar las dos ideas desde el principio:
un issue puede existir sin pushpin,
un pushpin puede existir como marcador visual sin convertirse necesariamente en issue,
y un issue con pushpin combina las dos cosas: workflow y ubicación espacial.
Ese es el modelo mental correcto.
Qué es realmente un pushpin
Un pushpin es un marcador visual dentro del visor de Autodesk.
Su función es guardar una localización dentro de un documento, modelo o plano. En el caso de un modelo 3D, normalmente incluye una posición en el espacio, una referencia al objeto seleccionado y el estado del visor en el momento de creación.
Dicho de forma menos ceremonial: el pushpin guarda el “dónde” y el “cómo estaba mirando el usuario”.
Eso es importante porque una incidencia dentro de un modelo 3D no se entiende solo con unas coordenadas. También necesitas recuperar el contexto visual. No basta con saber que algo ocurre en una posición X, Y, Z. Necesitas saber qué modelo estaba cargado, qué vista tenía el usuario, qué elemento estaba seleccionado, qué cámara estaba activa y qué parte del modelo estaba observando.
Por eso aparece el viewerState.
El viewerState es uno de los campos más importantes y peor entendidos del flujo. No representa la incidencia. Representa el estado del visor en el momento en que esa incidencia se crea o se visualiza. Es decir, la cámara, la orientación, los elementos visibles y otros datos que permiten reconstruir la escena.
En una integración real, esto es lo que permite que el usuario haga clic en un issue y el visor vuelva a colocarse donde debe, en lugar de lanzarlo a una posición aleatoria del modelo con la precisión emocional de una brújula rota.
Pushpin no significa issue, pero puede generar uno
Aquí está el punto clave.
Cuando en el visor de Autodesk se crea una incidencia localizada, normalmente se crea un issue que contiene información de pushpin.
No se crea “solo un icono”.
Tampoco se crea “solo un issue genérico”.
Se crea un issue asociado a un documento, modelo o plano, y dentro de ese issue se almacena la información necesaria para que el visor pueda representar el pushpin.
En BIM 360 Issues v2, esa información aparece dentro de linkedDocuments. En versiones anteriores o ejemplos antiguos se pueden encontrar referencias a pushpin_attributes, pero para desarrollo actual conviene trabajar con la estructura moderna.
Esto es importante porque muchos errores vienen de copiar ejemplos antiguos o de mezclar documentación de distintas generaciones de la API.
Si estás trabajando con Issues v2, la información del pushpin no vive en un campo aislado llamado pushpin. Vive dentro de la relación con el documento.
Ese detalle parece menor hasta que pierdes tres horas preguntándote por qué tu issue existe en el sistema pero no aparece correctamente dentro del visor. Tecnología moderna, ese milagro diario.
La estructura conceptual de un issue con pushpin
Un issue localizado dentro de un modelo combina varias capas:
La primera capa es el issue como entidad de negocio. Aquí entran campos como title, description, status, issueSubtypeId, assignedTo, assignedToType, dueDate, locationId, rootCauseId o atributos personalizados.
La segunda capa es el documento vinculado. Aquí aparece linkedDocuments, que indica a qué modelo, plano o documento está asociado el issue.
La tercera capa es la información espacial del pushpin. Dentro de linkedDocuments[].details se almacenan campos como position, objectId, externalId y viewerState.
La cuarta capa es el visor. Para que el usuario vea algo útil, el Viewer debe cargar la extensión correspondiente, recuperar los issues y convertir esos datos en elementos visuales que se puedan pintar, seleccionar y navegar.
Si una de estas capas falla, el resultado suele ser uno de estos tres clásicos:
el issue se crea pero no aparece en el modelo,
el pushpin aparece pero no se puede navegar correctamente,
o el servidor devuelve un error críptico que te invita a replantearte tus decisiones profesionales.
Flujo general de creación
El flujo típico para crear un issue localizado desde el visor sería algo así:
Primero cargas el modelo en Autodesk Viewer.
Después cargas la extensión de pushpins del visor, normalmente Autodesk.BIM360.Extension.PushPin.
A continuación, el usuario selecciona un punto del modelo o tú calculas una posición automáticamente a partir de una comprobación, una validación o una regla de control de calidad.
Después capturas la información necesaria: posición, elemento seleccionado, identificador externo, estado del visor y documento relacionado.
Con esos datos construyes el payload del issue.
Finalmente llamas a la API correspondiente para crear el issue.
En un flujo manual, el usuario coloca el pushpin en el visor.
En un flujo automatizado, como un quality checker, el sistema puede detectar errores y generar pushpins automáticamente. Por ejemplo, un modelo IFC que no cumple una regla, un elemento sin parámetro obligatorio, una categoría mal clasificada o una incidencia detectada por comparación entre modelos.
El concepto es el mismo. Lo que cambia es quién decide la posición: el usuario o la máquina.
Y aquí empieza lo interesante.
Issues creados desde el visor frente a issues generados automáticamente
Cuando el usuario crea un issue desde el visor, normalmente hay una acción humana explícita. Alguien navega, ve un problema, hace clic, escribe una descripción y crea la incidencia.
Cuando los issues se generan automáticamente, la lógica cambia.
Ya no partes de una observación humana. Partes de una validación.
Por ejemplo:
un elemento no cumple una especificación IDS,
un objeto no tiene clasificación,
un parámetro obligatorio está vacío,
una familia usa una nomenclatura incorrecta,
un elemento aparece fuera de una zona esperada,
o una comprobación geométrica detecta una incoherencia.
En esos casos, el sistema puede crear issues en el modelo para que el resultado de la validación no quede perdido en un JSON, un Excel o un dashboard externo.
Ese es el verdadero valor de los pushpins en procesos de control de calidad BIM: convertir resultados técnicos en incidencias accionables dentro del entorno donde trabaja el equipo.
No se trata solo de decir “hay 37 errores”.
Se trata de permitir que alguien abra el modelo, vea dónde están esos errores, acceda al contexto y pueda resolverlos dentro de un flujo de coordinación real.
Endpoint genérico de Issues v2
Para crear un issue estándar en BIM 360 Issues v2, el endpoint base es:
POST https://developer.api.autodesk.com/issues/v2/containers/{containerId}/issues
El containerId representa el contenedor de issues del proyecto. No es lo mismo que el projectId que se maneja en otras partes de APS, y esta diferencia es otra fuente habitual de confusión.
La API de Data Management te permite navegar hubs, proyectos, carpetas y versiones. Pero para crear issues necesitas trabajar contra el contenedor correcto de Issues.
El payload mínimo para crear un issue puede ser relativamente simple, pero cuando quieres crear un issue localizado en un modelo necesitas incluir linkedDocuments.
Una estructura simplificada podría tener este aspecto:
{
"title": "Elemento sin clasificación",
"description": "El elemento seleccionado no tiene informado el parámetro de clasificación requerido.",
"issueSubtypeId": "ISSUE_SUBTYPE_ID",
"status": "open",
"linkedDocuments": [
{
"type": "TwoDVectorPushpin",
"urn": "DOCUMENT_URN",
"createdAtVersion": 1,
"details": {
"position": {
"x": 12.34,
"y": 56.78,
"z": 9.10
},
"objectId": 1234,
"externalId": "ELEMENT_EXTERNAL_ID",
"viewerState": {}
}
}
]
}
Este ejemplo no pretende ser un payload universal. Pretende mostrar la idea estructural.
El issue se crea como issue.
La localización se define mediante linkedDocuments.
El pushpin aparece porque el issue queda asociado a un documento y contiene detalles espaciales que el visor puede interpretar.
Parámetros principales del issue
title
El title es el título visible del issue.
En integraciones automáticas conviene que sea corto, reconocible y agrupable. No debería ser una novela ni una descripción técnica interminable.
Un mal título sería:
Error detectado por el sistema de validación automática de parámetros BIM en elemento de modelo federado número 348723
Un título más útil sería:
Elemento sin clasificación
O, si estás generando issues desde reglas:
IDS incumplido: clasificación obligatoria
El título debe permitir identificar el problema en una lista. La explicación completa puede ir en description.
description
La description sirve para explicar el problema con más contexto.
En un flujo de control de calidad, aquí puedes incluir la regla incumplida, el valor esperado, el valor encontrado y una recomendación de corrección.
Por ejemplo:
El elemento no cumple la regla de clasificación definida para este entregable.
Valor esperado: código de clasificación informado.
Valor encontrado: vacío.
Revisa el parámetro correspondiente antes de volver a publicar el modelo.
Este campo es especialmente importante cuando los issues se generan automáticamente, porque el usuario que los recibe no tiene por qué conocer la lógica interna del validador.
La máquina detecta el problema, pero la descripción debe estar escrita para una persona.
Una idea revolucionaria, aparentemente.
issueSubtypeId
El issueSubtypeId indica el subtipo de issue que se va a crear.
Este campo es importante porque los tipos y subtipos suelen estar configurados en el proyecto. No deberías inventarlo ni hardcodearlo alegremente en producción.
Lo razonable es recuperar previamente los tipos y subtipos disponibles para el proyecto, mapearlos contra tus reglas internas y usar el subtipo correspondiente.
Por ejemplo, podrías tener una relación de este tipo:
reglas de clasificación → subtipo “Calidad de información”,
reglas geométricas → subtipo “Coordinación”,
reglas documentales → subtipo “Documentación”,
reglas de seguridad → subtipo “Seguridad”.
La decisión depende de cómo esté configurado el entorno del cliente o del proyecto.
En un producto reutilizable, este mapeo debería ser configurable. En un script interno, puedes permitirte ser más directo, aunque luego no te quejes si el proyecto cambia y todo empieza a fallar con la delicadeza de un piano cayendo por una escalera.
status
El status define el estado inicial del issue.
Lo normal es crear el issue como open, aunque depende del workflow permitido por el proyecto.
No todos los estados son siempre válidos en todos los contextos. En algunos casos conviene consultar qué estados están permitidos para el usuario y para el tipo de issue antes de intentar actualizarlo.
Para creación automática, mi recomendación es no intentar ser demasiado listo al principio.
Crea el issue en estado abierto y deja que el flujo normal del proyecto lo gestione.
Automatizar también el ciclo de vida puede tener sentido más adelante, pero si estás empezando, mezclar validación, asignación, estados y cierre automático suele ser una receta perfecta para fabricar caos con API key.
assignedTo y assignedToType
Estos campos permiten asignar el issue a alguien.
assignedTo contiene el identificador del destinatario.
assignedToType indica qué tipo de destinatario es: usuario, empresa, rol u otro valor admitido por la API.
No conviene enviar uno sin el otro.
En flujos automáticos, la asignación es una decisión delicada. Puedes asignar al responsable de disciplina, al coordinador BIM, al autor del modelo, a una empresa o a un rol.
Pero cuidado: si asignas mal, el sistema deja de ser una ayuda y se convierte en una máquina de generar ruido político. Y no hay API que arregle eso.
Para una primera versión de una herramienta, muchas veces es mejor crear los issues sin asignación directa o asignarlos a un rol genérico de revisión BIM, dependiendo de cómo trabaje el equipo.
dueDate
La fecha límite puede ser útil, pero no siempre debe automatizarse.
Si todos los issues automáticos se crean con la misma fecha límite arbitraria, acabarás generando presión sin criterio. Si la fecha depende de la fase, disciplina o severidad, entonces sí puede tener sentido.
Por ejemplo:
errores críticos → 3 días,
errores medios → 7 días,
observaciones leves → próxima revisión.
Pero esto ya implica tener una lógica de severidad clara.
Sin esa lógica, mejor no fingir precisión.
locationId y locationDescription
Los campos de ubicación permiten vincular el issue a una localización del proyecto.
No hay que confundirlos con la posición del pushpin.
La posición del pushpin responde a “dónde está esto en el modelo”.
La ubicación del issue responde a “a qué zona, nivel, área o localización del proyecto pertenece”.
Son conceptos relacionados, pero no idénticos.
En un modelo bien estructurado, podrías inferir la localización a partir del elemento, del nivel, de una zona o de datos del propio modelo. Pero esa inferencia no siempre es trivial.
Si no tienes una relación fiable entre elemento y ubicación, no conviene inventarla. Un locationDescription textual puede ser suficiente para una primera aproximación.
rootCauseId
La causa raíz puede aportar valor si el proyecto trabaja realmente con análisis de causas.
En muchos entornos, este campo existe pero se rellena de forma mecánica o directamente se ignora.
En una automatización de calidad BIM puede ser interesante mapear causas como:
información incompleta,
nomenclatura incorrecta,
modelo desactualizado,
clasificación no conforme,
coordinación pendiente,
error geométrico,
incumplimiento de estándar.
Pero, de nuevo, solo tiene sentido si después alguien va a analizar esos datos.
Si nadie va a usar la causa raíz, rellenarla automáticamente solo sirve para decorar el cadáver.
watchers
Los watchers permiten añadir observadores al issue.
Puede ser útil cuando quieres que determinados perfiles estén informados sin ser responsables directos.
En integraciones de control de calidad, podrías añadir como watchers al BIM Manager, al coordinador de disciplina o al responsable del paquete.
Pero hay que usarlo con moderación. Convertir cada issue automático en una notificación para media empresa es una forma rápida de conseguir que todo el mundo ignore tus automatizaciones.
La automatización útil reduce ruido.
La mala automatización lo multiplica y además lo hace más rápido.
linkedDocuments: donde empieza realmente el pushpin
El bloque linkedDocuments es la parte crítica cuando quieres que el issue esté relacionado con un modelo o plano.
Aquí se define el vínculo entre el issue y el documento en el que se va a representar el pushpin.
Una estructura típica contiene:
type,
urn,
createdAtVersion,
y details.
Cada uno tiene su propia trampa, porque Autodesk no podía simplemente poner “modelo”, “versión” y “punto”. Eso habría sido demasiado amable.
type
El type indica el tipo de relación visual.
En los flujos documentados aparecen valores como TwoDVectorPushpin y TwoDRasterPushpin.
Aunque estés trabajando con modelos 3D, verás referencias que pueden resultar confusas por la nomenclatura. Lo importante es usar el tipo esperado por el endpoint y por el flujo concreto que estés implementando.
No conviene asumir que cualquier string inventado va a funcionar. Este campo debe seguir los valores admitidos por la API.
urn
El urn identifica el documento asociado.
Este es uno de los puntos donde es fácil equivocarse.
En APS hay distintos identificadores para hubs, proyectos, carpetas, items, versiones y derivados. No todos sirven para lo mismo.
Para un pushpin asociado a un issue, necesitas referenciar correctamente el documento al que pertenece la incidencia. Si usas el URN incorrecto, el issue puede crearse, pero no aparecer donde esperas.
El síntoma típico es frustrante: la API responde bien, el issue existe, pero el visor no lo muestra como tú querías.
Eso suele indicar que el problema no está en el issue, sino en la relación con el documento.
createdAtVersion
Este campo indica la versión del documento en la que se creó el pushpin.
Esto es fundamental en entornos donde los modelos se publican varias veces.
Un issue no existe en el vacío. Se creó sobre una versión concreta de un documento. Si el modelo evoluciona, esa referencia ayuda a entender el contexto original.
En flujos de validación automática, esto es especialmente importante. Si generas issues después de analizar una versión publicada del modelo, deberías guardar claramente contra qué versión se generaron.
Si no lo haces, luego tendrás incidencias apuntando a elementos que han cambiado, desaparecido o se han movido.
Y entonces empieza el deporte favorito de la construcción digital: discutir si el problema es del modelo, de la API, del coordinador o de “la versión que abrió Juan”.
details: la parte espacial del pushpin
Dentro de linkedDocuments[].details aparece la información que permite al visor representar correctamente el pushpin.
Aquí los campos importantes son:
position,
objectId,
externalId,
y viewerState.
position
La position representa la posición del pushpin.
Normalmente se expresa con coordenadas x, y, z.
Este campo responde a la pregunta: ¿dónde se coloca el marcador dentro del espacio del visor?
Cuando el usuario crea manualmente el pushpin, esa posición puede obtenerse a partir de la interacción con el visor.
Cuando el sistema lo genera automáticamente, necesitas calcularla.
Y aquí aparece un problema interesante: muchas validaciones BIM detectan un elemento, pero no necesariamente un punto exacto.
Si detectas que una puerta tiene un parámetro vacío, ¿dónde colocas el pushpin?
Puedes usar el centroide del elemento.
Puedes usar el bounding box.
Puedes usar un punto representativo.
Puedes intentar usar la posición de inserción.
Cada opción tiene implicaciones.
El centroide puede caer en un sitio poco intuitivo. El bounding box puede funcionar bien para elementos simples, pero ser menos claro en geometrías complejas. La posición de inserción puede no representar visualmente el problema.
No hay una respuesta universal.
En una herramienta seria, esta decisión debería depender del tipo de elemento y del tipo de incidencia.
Para una primera versión, usar un punto representativo del elemento suele ser suficiente. No perfecto, pero suficiente. La perfección geométrica es preciosa hasta que te impide terminar nada, esa vieja tragedia.
objectId
El objectId identifica el objeto dentro del visor.
Suele corresponder al identificador interno que usa Autodesk Viewer para seleccionar o aislar elementos.
Este campo es útil porque permite relacionar el pushpin con un elemento concreto del modelo cargado.
Pero no conviene tratarlo como un identificador universal eterno.
El objectId depende del modelo procesado y del entorno del visor. Si cambia la versión, la traducción o la estructura del modelo, puede no comportarse como esperas.
Sirve para interactuar con el visor, seleccionar, aislar o navegar, pero no debería ser tu única referencia persistente de negocio.
externalId
El externalId suele ser más interesante para integraciones BIM.
Representa el identificador externo del elemento, muchas veces relacionado con el GUID o identificador persistente procedente del modelo original.
En flujos de calidad, este campo es muy valioso porque permite conectar el issue con el dato BIM que estás validando.
Si estás comprobando reglas sobre elementos IFC, Revit o modelos federados, el externalId puede ayudarte a mantener la relación entre:
la regla incumplida,
el elemento validado,
el issue creado,
y la representación visual en el visor.
En otras palabras: objectId te ayuda a hablar con el visor; externalId te ayuda a hablar con el modelo y con tus propios datos.
No siempre estarán disponibles de la misma forma, y por eso conviene probar bien el flujo con modelos reales, no con el típico modelo de ejemplo donde todo funciona y hasta los parámetros parecen educados.
viewerState
El viewerState guarda el estado del visor.
Este campo es el que permite restaurar la vista desde la que se creó el pushpin.
Puede incluir cámara, orientación, selección, visibilidad de elementos y otros datos necesarios para reconstruir el contexto.
En la práctica, viewerState es lo que hace que al abrir un issue no solo sepas que existe una incidencia, sino que puedas volver a verla como la vio quien la creó.
En flujos automatizados, la generación del viewerState puede ser más compleja, porque no siempre hay un usuario navegando manualmente.
Puedes generar una vista a partir del elemento afectado, encuadrarlo, aislarlo y guardar ese estado. O puedes usar una vista estándar si el objetivo es simplemente localizar el problema.
La decisión depende del tipo de herramienta.
Si estás creando una integración avanzada, merece la pena cuidar este punto. Un issue que abre una vista clara se resuelve antes que uno que obliga al usuario a buscar el elemento como si estuviera jugando a “Dónde está Wally”, edición MEP.
El endpoint específico de Model Coordination
Además del endpoint genérico de Issues v2, existe un flujo específico para Model Coordination.
El endpoint relevante tiene esta forma:
POST https://developer.api.autodesk.com/modelcoordination/v2/containers/{containerId}/modelsets/{modelSetId}/issues
Este endpoint crea un issue de inspección visual dentro de un model set.
Aquí la lógica es ligeramente distinta.
No estás creando simplemente un issue genérico asociado a un documento. Estás creando una incidencia en el contexto de Model Coordination, normalmente relacionada con revisión visual, coordinación o clash management.
El payload puede incluir un objeto pushpin de forma más directa, además de campos propios del issue.
Una estructura simplificada podría parecerse a esto:
{
"title": "Conflicto detectado en coordinación",
"description": "Incidencia generada desde revisión visual del model set.",
"issueSubTypeId": "ISSUE_SUBTYPE_ID",
"assignedTo": "USER_OR_ROLE_ID",
"assignedToType": "user",
"pushpin": {
"type": "TwoDVectorPushpin",
"position": {
"x": 12.34,
"y": 56.78,
"z": 9.10
},
"objectId": 1234,
"externalId": "ELEMENT_EXTERNAL_ID",
"viewerState": {}
}
}
Aquí hay un detalle absurdo pero importante: en algunos endpoints aparece issueSubtypeId y en otros issueSubTypeId.
La diferencia está en la mayúscula de la T.
Sí, esto existe.
Sí, puede romper tu integración.
No, no parece diseñado por alguien que haya sufrido suficiente.
Por eso no conviene asumir que todos los endpoints de Autodesk usan exactamente la misma nomenclatura. Hay que revisar el endpoint concreto, copiar el nombre exacto del campo y validar el payload contra la referencia correspondiente.
Cuándo usar Issues v2 y cuándo usar Model Coordination
La pregunta práctica es: ¿qué endpoint uso?
La respuesta depende del origen del problema.
Si estás creando un issue general de proyecto, asociado a un documento o modelo, el flujo de Issues v2 con linkedDocuments suele ser el punto de partida.
Si estás creando un issue como resultado de una revisión de coordinación dentro de un model set, especialmente en flujos de Model Coordination, tiene más sentido usar el endpoint específico de Model Coordination.
Dicho de otra forma:
si el issue nace de una validación de información, una revisión de calidad o una herramienta externa, probablemente mirarás hacia Issues v2;
si el issue nace de coordinación visual, clashes o revisión dentro de model sets, probablemente mirarás hacia Model Coordination.
No es una frontera perfecta, pero es una pauta útil.
Lo importante es no intentar forzar todos los casos dentro del mismo endpoint solo porque ambos terminan siendo “issues” en la interfaz.
En Autodesk, dos cosas que se llaman parecido no tienen por qué compartir la misma API. Es parte del encanto. Como una casa antigua, pero con OAuth.
Autenticación y permisos
Para trabajar con estos flujos necesitas autenticación OAuth contra APS.
En muchos escenarios relacionados con BIM 360, ACC, documentos del usuario e issues, el flujo habitual es 3-legged OAuth, porque estás actuando en nombre de un usuario con permisos concretos dentro de un proyecto.
No basta con tener un token válido.
El usuario debe tener permisos reales para ver el proyecto, acceder al documento y crear o modificar issues.
Esto es importante porque muchos errores no son técnicos, sino de permisos.
Puedes tener bien el endpoint, bien el payload y bien el token, y aun así recibir un 403 porque el usuario no tiene permiso para crear issues en ese proyecto.
Por eso, antes de crear automatizaciones serias, conviene validar:
que la aplicación está correctamente registrada,
que el usuario ha autorizado los scopes necesarios,
que la app tiene acceso a la cuenta o proyecto correspondiente,
que el usuario puede ver el documento,
que el usuario puede crear issues,
y que el tipo/subtipo de issue existe en ese proyecto.
En otras palabras: antes de culpar al JSON, mira los permisos.
El JSON es culpable muchas veces, pero no siempre. Hay que ser justos incluso con los objetos.
Scopes habituales
Los scopes necesarios dependen del flujo exacto.
Para trabajar con visor, documentos e issues, suelen aparecer scopes relacionados con lectura de viewables, lectura de datos, escritura de datos y creación de datos.
Por ejemplo:
viewables:read para cargar modelos en el visor,
data:read para leer información de proyectos, documentos o issues,
data:write para escribir o actualizar información,
data:create para crear recursos.
No hay que pedir más scopes “por si acaso”.
Pedir permisos excesivos complica la revisión de seguridad y aumenta el riesgo de la integración. Lo correcto es pedir lo mínimo necesario para el flujo real.
Sé que “pedir todo y ya veremos” es tentador. También lo es usar admin para todo en una base de datos. Luego vienen las auditorías y el llanto.
Recuperar issues y pintarlos en el visor
Crear el issue es solo la mitad del flujo.
La otra mitad es recuperarlo y mostrarlo correctamente en el visor.
El patrón general sería:
cargar el modelo,
recuperar issues asociados al documento,
transformar los datos de la API al formato esperado por la extensión de pushpins,
y llamar al método correspondiente para pintarlos en el visor.
En Viewer v7, conviene revisar bien los ejemplos actualizados, porque hay diferencias respecto a patrones antiguos. En versiones modernas, el patrón recomendado para cargar elementos en la extensión no es copiar sin pensar ejemplos viejos de createItem, sino usar el flujo actual de carga de items.
Aquí es donde conviene fijar versión del Viewer en producción.
No dejes que una herramienta crítica dependa de “la última versión disponible” sin probar. Eso está bien para demos. Para producción es una invitación a que un martes cualquiera algo deje de funcionar y nadie sepa por qué.
Diferencia entre pushpin, markup y issue
No todo marcador visual debe convertirse en issue.
Esto es especialmente importante si estás diseñando herramientas propias sobre Autodesk Viewer.
Puedes tener tres niveles:
Un markup o marcador temporal.
Un pushpin visual controlado por tu aplicación.
Un issue formal dentro de BIM 360 o ACC.
El marcador temporal sirve para orientar al usuario, señalar algo en una sesión o representar información propia de la aplicación.
El issue formal sirve cuando necesitas trazabilidad, responsable, estado, comentarios, adjuntos y ciclo de vida.
La regla es sencilla:
si necesitas workflow, crea un issue;
si solo necesitas contexto visual, no crees un issue;
si necesitas las dos cosas, crea un issue con pushpin.
Crear issues para todo es mala idea.
En un quality checker, por ejemplo, no todos los avisos tienen por qué convertirse en incidencias formales. Puede haber errores críticos, advertencias, recomendaciones y simples notas informativas.
Si conviertes cada advertencia en un issue, el sistema se llenará de ruido.
Y cuando todo es urgente, nada es urgente. Otra frase que la industria conoce perfectamente y aun así ignora con disciplina olímpica.
Aplicación práctica: quality checker BIM
Imaginemos una herramienta de control de calidad BIM.
El sistema analiza un modelo y detecta que varios elementos no cumplen las reglas establecidas. Puede generar un informe, una tabla o un dashboard.
Eso está bien, pero tiene una limitación evidente: el resultado vive fuera del modelo.
El coordinador tiene que leer el informe, buscar el elemento, localizarlo en el visor, entender el problema y comunicarlo al equipo.
Los pushpins permiten cerrar ese círculo.
Cada incumplimiento relevante puede convertirse en un issue localizado dentro del modelo. Así, el resultado de la validación no queda como un documento externo, sino como una lista de incidencias navegables y accionables.
Un flujo posible sería:
analizar el modelo,
detectar elementos no conformes,
calcular un punto representativo para cada elemento,
recuperar objectId y externalId,
generar un viewerState útil,
crear un issue con linkedDocuments,
y permitir que el equipo lo revise desde el visor.
Esto transforma una validación técnica en un flujo de coordinación.
Y esa es la diferencia entre una herramienta que solo escupe errores y una herramienta que realmente ayuda a corregirlos.
Qué información conviene guardar en tu propia base de datos
Aunque el issue exista en Autodesk, no siempre conviene depender únicamente de APS como fuente de toda la lógica interna de tu herramienta.
En una integración propia, puede tener sentido guardar también:
el identificador del issue creado,
la regla que lo generó,
el elemento afectado,
el identificador externo,
la versión del modelo analizada,
la fecha de validación,
el resultado original de la comprobación,
y el estado interno de sincronización.
Esto permite auditar qué ocurrió, evitar duplicados y actualizar issues existentes en lugar de crear nuevos cada vez que se ejecuta la validación.
Ese último punto es crítico.
Una herramienta mal diseñada puede crear los mismos 200 issues cada vez que se analiza el modelo.
Una herramienta bien diseñada detecta si el problema ya existe, actualiza el issue si sigue vigente y lo cierra o marca como resuelto si el problema desaparece.
La diferencia entre ambas es la diferencia entre automatización y vandalismo con API.
Evitar duplicados
Uno de los problemas más importantes en flujos automáticos es la duplicación.
Si cada validación crea issues nuevos, el proyecto se degrada rápidamente.
Para evitarlo, conviene construir una clave lógica de incidencia.
Por ejemplo:
modelo,
versión o línea de documento,
regla,
elemento,
tipo de problema.
Con esa combinación puedes decidir si un issue ya existe.
Si existe y el problema continúa, puedes mantenerlo abierto o actualizar su descripción.
Si existe y el problema se ha corregido, puedes cerrarlo o cambiar su estado según el workflow del proyecto.
Si no existe, creas uno nuevo.
Este patrón es mucho más robusto que lanzar issues sin memoria.
La automatización no debería olvidar lo que hizo ayer. Para eso ya estamos los humanos.
Qué pasa cuando cambia el modelo
Los modelos cambian.
Los elementos se eliminan.
Los identificadores pueden variar.
Las versiones nuevas sustituyen a versiones antiguas.
Y los pushpins creados sobre una versión concreta pueden perder precisión si el modelo evoluciona.
Por eso es importante guardar la versión del documento y no confiar únicamente en una posición espacial.
Si el elemento sigue existiendo y puedes relacionarlo mediante externalId, es posible mantener cierta continuidad.
Si el elemento desaparece, tal vez el issue deba cerrarse, marcarse como obsoleto o quedar vinculado a la versión en la que se detectó.
No hay una única solución válida, pero sí una mala: ignorar el versionado.
En BIM, ignorar el versionado es como construir una escalera y luego sorprenderse de que tenga niveles.
Capturas y adjuntos
En algunos flujos, especialmente en coordinación visual, puede tener sentido añadir capturas o adjuntos al issue.
Una captura ayuda a entender rápidamente el problema sin tener que cargar todo el modelo.
Pero no debería sustituir al pushpin.
La captura es evidencia visual.
El pushpin es navegación espacial.
El issue es gestión.
Cada pieza tiene su función.
Cuando se mezclan sin criterio, acabas con incidencias que tienen imagen pero no ubicación, ubicación pero sin contexto, o descripción sin elemento afectado.
Y entonces nadie sabe si tiene que corregir un muro, una familia, una vista o su carrera profesional.
Buenas prácticas al generar pushpins automáticamente
La primera buena práctica es no crear issues para todo.
Antes de convertir una validación en issue, define qué severidad justifica una incidencia formal.
La segunda es guardar una relación interna entre regla, elemento e issue. Sin eso, no podrás sincronizar bien.
La tercera es usar títulos cortos y descripciones útiles.
La cuarta es cuidar el viewerState. Un issue que abre una mala vista es un issue a medio hacer.
La quinta es no hardcodear tipos, subtipos, usuarios o roles salvo que estés en un entorno muy controlado.
La sexta es validar permisos antes de culpar al endpoint.
La séptima es probar con modelos reales, no solo con modelos limpios de ejemplo.
Los modelos reales tienen geometrías raras, versiones acumuladas, parámetros inconsistentes, elementos duplicados y decisiones tomadas un viernes a las seis de la tarde.
Ahí es donde se comprueba si una integración sirve para producción.
Errores habituales
El primer error habitual es usar el URN equivocado.
El issue se crea, pero no aparece como pushpin donde esperabas.
El segundo es olvidar createdAtVersion.
El issue queda mal contextualizado respecto a la versión del documento.
El tercero es no guardar viewerState.
El pushpin existe, pero la navegación es pobre.
El cuarto es depender solo de objectId.
Funciona en una sesión o versión concreta, pero puede ser frágil como referencia persistente.
El quinto es generar issues duplicados en cada ejecución.
Esto convierte una herramienta de calidad en una fábrica de basura.
El sexto es mezclar documentación de BIM 360, ACC, Forma y Model Coordination sin comprobar qué API aplica realmente al proyecto.
Este es probablemente el error más común.
Autodesk ha ido evolucionando el ecosistema, pero la documentación conserva capas históricas. Hay APIs que siguen estando bajo BIM 360, endpoints que aparecen también en ACC, referencias a Forma y tutoriales que no siempre cuentan toda la película.
Por eso, antes de implementar, hay que responder tres preguntas:
¿Estoy trabajando con BIM 360 o ACC/Forma?
¿Quiero crear un issue genérico o un issue de Model Coordination?
¿Necesito un issue formal o solo un marcador visual?
Hasta que esas tres preguntas no estén claras, escribir código es prematuro.
Y sí, todos lo hemos hecho al revés alguna vez. La diferencia es aprender antes de convertirlo en arquitectura.
Cuándo no usar pushpins
No uses pushpins si la incidencia no tiene una ubicación espacial clara.
Por ejemplo, si el problema es que falta un documento, que una entrega no cumple una nomenclatura general o que una disciplina no ha subido su modelo, no necesitas un pushpin.
Eso es un issue de proceso o documentación.
Forzar una posición en el modelo solo añade una falsa precisión.
Tampoco uses pushpins si solo quieres representar resultados temporales de análisis.
Si el usuario necesita revisar una serie de puntos durante una sesión, quizá baste con markups propios, overlays o marcadores temporales.
El pushpin con issue tiene sentido cuando el problema debe entrar en un workflow de seguimiento.
Si no hay seguimiento, no hay responsable, no hay estado y no hay trazabilidad, probablemente no necesitas un issue.
Necesitas una anotación.
La diferencia parece pequeña, pero a nivel de producto es enorme.
Conclusión
Crear issues dentro de un modelo 3D con APS no consiste simplemente en llamar a la API de issues.
Consiste en entender cómo Autodesk separa la incidencia como objeto de gestión y el pushpin como representación espacial dentro del visor.
El issue responde a qué ocurre, quién debe resolverlo, en qué estado está y cómo se documenta.
El pushpin responde a dónde ocurre y cómo volver a verlo dentro del modelo.
Cuando combinas ambas piezas correctamente, puedes construir herramientas muy potentes: validadores BIM que generan incidencias navegables, revisiones de calidad conectadas al modelo, flujos de coordinación más claros y sistemas de seguimiento que no se quedan encerrados en una hoja Excel.
Pero si no separas bien los conceptos, acabarás peleándote con endpoints, URNs, versiones, estados del visor y campos que se llaman casi igual pero no exactamente igual.
La clave es esta:
un pushpin no es un issue;
un issue no necesita siempre un pushpin;
pero cuando necesitas trazabilidad y localización dentro del modelo, el issue con pushpin es la pieza correcta.
Y una vez entiendes eso, la API deja de parecer una pared de documentación desordenada y empieza a convertirse en una herramienta útil.
No más amable, tampoco exageremos.
Pero sí útil.

Responses