Third-AI-Uniandes — Flujos HTTP para APIM

Documentación de cómo el CLI de AI Uniandes consume las APIs para integración con APIM.

Base URL: Sustituya https://{apim-host}/{api-suffix} por la URL de su APIM.

Servicios del CLI

ServicioUsoScope OAuth2Nota
UploadDocumentUpload, estado, eliminaciónUploadDocumentPrincipal de ingesta
DocumentClassifierDocumentGroups + batchDocumentClassifierVisibilidad restringida
ClientAssistantChat con asistentesClientAssistantPreguntas RAG
OnBaseNavegación de archivosOnBaseRequiere bearer

1. Autenticación OAuth2 client_credentials

sequenceDiagram
    participant Client
    participant EntraID as Microsoft Entra ID
    participant APIM
    Client->>EntraID: POST /oauth2/v2.0/token (client_credentials + scope)
    EntraID-->>Client: access_token (JWT)
    Client->>APIM: API call con Authorization: Bearer {token}
    APIM-->>Client: Response
POST https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token

Scopes por servicio

ServicioScope
UploadDocumentapi://FA-<env>-AIUniandes-UploadDocument/.default
DocumentClassifierapi://FA-<env>-AIUniandes-DocumentClassifier/.default
ClientAssistantapi://FA-<env>-AIUniandes-ClientAssistant/.default
OnBaseapi://FA-<env>-AIUniandes-OnBase/.default

Ejemplo de obtención de token

HTTP Request
POST https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id={client_id}
&client_secret={client_secret}
&scope=api://FA-QA-AIUniandes-UploadDocument/.default

Headers comunes

HTTP Headers
Accept: application/json
Authorization: Bearer {access_token}
Content-Type: application/json

2. Flujo de ingesta para asistentes RAG

sequenceDiagram
    participant Client
    participant APIM
    participant Upload as UploadDocument API
    Client->>APIM: POST /documents/upload/assistant (multipart)
    APIM->>Upload: forward
    Upload-->>APIM: file_id, status: UPLOADED
    APIM-->>Client: 200 OK + file_id
    Client->>APIM: POST /documents/process {file_id, type: context_assistant}
    APIM->>Upload: forward
    Upload-->>APIM: 202 Accepted
    APIM-->>Client: 202 Accepted
    loop Polling cada 5s (max 300s)
        Client->>APIM: GET /document/{id}/status
        APIM-->>Client: status: PROCESSING
    end
    Client->>APIM: GET /document/{id}/status
    APIM-->>Client: status: READY

Upload del archivo

POST /api/v1/documents/upload/assistant
CampoTipoValorRequerido
filebinarioContenido del archivo
sourcetextoCONTEXT_ASSISTANT
application_idtextoUUID del asistenteNo
conversation_idtextoUUID de conversaciónNo
JSON Response 200
{
  "file_id": "2da40ce5-4c9f-4cce-a76d-7ff7304c4fd1",
  "file_name": "documento.pdf",
  "status": "UPLOADED"
}

Procesamiento

POST /api/v1/documents/process
JSON Request
{
  "file_id": "{file_id}",
  "id_application": "{assistant_id}",
  "type": "context_assistant"
}
Importante: El campo type debe ser exactamente context_assistant (guión bajo).

Polling de estado

GET /api/v1/document/{document_id}/status
JSON Response 200
{
  "id": "{document_id}",
  "filename": "documento.pdf",
  "status": "READY",
  "source": "CONTEXT_ASSISTANT",
  "blob_name": "container/documento.pdf",
  "id_assistant": "{assistant_id}",
  "error": false
}

Estados terminales

EstadoSignificadoAcción
READYDocumento listoFin exitoso
PROCESSEDProcesamiento completadoFin exitoso
ERRORError en procesamientoRevisar logs
FAILEDFallo irrecuperableReintentar
DELETEDEliminadoN/A

3. Flujo de chat con asistentes

sequenceDiagram
    participant Client
    participant APIM
    participant Assistant as ClientAssistant API
    Client->>APIM: POST /ai-assistant/chat/{assistant_id}
    Note right of Client: question, model, idConversation
    APIM->>Assistant: forward + Bearer token
    Assistant-->>APIM: answer, links, keyWords
    APIM-->>Client: 200 OK
POST /api/v1/ai-assistant/chat/{assistant_id}

Modelos disponibles

Aliasmodelmodel_label
gpt-5GPT_5_CHAT_UNIANDESOpen AI gpt-5-chat
gpt-4.1GPT_4_1_CHAT_UNIANDESOpen AI gpt-4.1-chat
gpt-4oGPT_4o_CHAT_UNIANDESOpen AI gpt-4o-chat
deepseekDEEPSEEK_R1_CHAT_UNIANDESDeepSeek R1 chat

Payload completo

JSON Request
{
  "id": "{message_uuid}",
  "userName": "script-rag-chat",
  "roles": "ADMINISTRATIVE,STUDENT,TEACHER,ADMINISTRATOR-ASSISTANT,OWNER-ASSISTANT,USER-TD",
  "state": "INITIALIZED",
  "category": "",
  "question": "Cual es la politica de homologaciones?",
  "answer": "   ",
  "answerTyping": "   ",
  "answerRating": 0,
  "reasonRating": "",
  "refinedAnswer": "",
  "academicCategory": null,
  "keyWords": [],
  "links": [],
  "restrictionService": null,
  "idConversation": "{conversation_uuid}",
  "files": [],
  "model": "GPT_5_CHAT_UNIANDES",
  "model_label": "Open AI gpt-5-chat",
  "is_open": "NO"
}

Campos de respuesta

CampoTipoDescripción
answerstringTexto de respuesta
idUUIDID del mensaje
idConversationUUIDReutilizar para el hilo
keyWordsarrayPalabras clave
linksarrayReferencias citadas

4. Descarga de metadata desde OnBase

flowchart TD
    A[Inicio] --> B{Modo?}
    B -->|Navegacion| C[GET /onbase/files?path=X]
    B -->|Busqueda| D[GET /onbase/files?search=X]
    C --> E{Tiene subcarpetas?}
    E -->|Si| F[Encolar subcarpetas]
    F --> C
    E -->|No| G[Recoger archivos]
    D --> H{next_cursor?}
    H -->|Si| I[Repetir con cursor]
    I --> D
    H -->|No| G
    G --> J[Exportar Excel]

Listado por navegación

GET /api/v1/onbase/files?path={path}&page_size={n}
HTTP Request
GET /api/v1/onbase/files?path=Secretaria/Actas/&page_size=50
Authorization: Bearer {onbase_token}
Accept: application/json

Búsqueda paginada

GET /api/v1/onbase/files?search={texto}&page_size={n}&cursor={cursor}

Mapeo OnBase → Excel

Campo ExcelOrigenTransformación
sourceFijo: ONBASE
document_onbase_idfile_idDirecto
namenameDirecto
typologydocument_typeDirecto
categorypathDirecto
visibilityvisibilityCLASSIFIED → RESTRICTED
actionFijo: NEW

5. Ingesta institucional simple

sequenceDiagram
    participant Client
    participant APIM
    participant Upload as UploadDocument
    participant Classifier as DocumentClassifier
    alt source = PORTAL_WEB
        Client->>APIM: POST /document/upload/institutional (multipart)
    else source = ONBASE
        Client->>APIM: POST /documents/upload/onbase {file_id, source}
    end
    APIM-->>Client: file_id
    opt visibility = RESTRICTED
        Client->>APIM: POST /document-groups {file_id, allowed_groups, allowed_users}
        APIM-->>Client: 201 Created
    end
    Client->>APIM: POST /document-groups/classify/batch {file_ids}
    APIM-->>Client: job_id
    loop Polling
        Client->>APIM: GET /document-groups/classify/status/{job_id}
        APIM-->>Client: status
    end

Upload local

POST /api/v1/document/upload/institutional
HTTP Request (multipart)
POST /api/v1/document/upload/institutional
Authorization: Bearer {upload_token}
Content-Type: multipart/form-data

file: documento.pdf (binary)
application_id: {application_id}

Upload desde OnBase

POST /api/v1/documents/upload/onbase
JSON Request
{
  "file_id": "{document_onbase_id}",
  "source": "CONTEXT_INSTITUTIONAL"
}

Crear DocumentGroup (RESTRICTED)

POST /api/v1/document-groups
JSON Request
{
  "file_id": "{file_id}",
  "application_id": "{application_id}",
  "allowed_groups": [{ "name_group": "Secretaria-General" }],
  "allowed_users": [{ "username": "[email protected]" }]
}

Actualizar DocumentGroup

PUT /api/v1/document-groups/{file_id}
JSON Request
{
  "allowed_groups": [{ "name_group": "Secretaria-General" }],
  "allowed_users": [{ "username": "[email protected]" }]
}

Clasificación batch

POST /api/v1/document-groups/classify/batch
JSON Request
{
  "file_ids": ["{file_id}"],
  "application_id": "{application_id}"
}
JSON Response 202
{
  "data": {
    "job_id": "{job_id}",
    "status_url": "/api/v1/document-groups/classify/status/{job_id}"
  }
}

Polling clasificación

GET /api/v1/document-groups/classify/status/{job_id}
EstadoTerminal
Completed
Failed
RunningNo (seguir polling)

6. Eliminación de archivo institucional

sequenceDiagram
    participant Client
    participant APIM
    Client->>APIM: GET /document/{id}/detail
    APIM-->>Client: document metadata
    Client->>APIM: GET /document-groups/by-file/{id}
    alt Existe DocumentGroup
        APIM-->>Client: {id: ...}
        Client->>APIM: DELETE /document-groups/{file_id}
        APIM-->>Client: 204 No Content
    else No existe
        APIM-->>Client: 404
    end
    Client->>APIM: DELETE /document/delete/{id}
    APIM-->>Client: 204 No Content

7. Recomendaciones APIM

Producto APIMEndpoints
Ingesta asistentesupload assistant, process, status, delete
Chat asistentes/ai-assistant/chat/{id}
Ingesta institucionalupload institutional, upload onbase, document-groups, classify
Consulta OnBase/onbase/files

8. Diferencias importantes

1. type en POST /documents/process = context_assistant (guión bajo)
2. Ingesta institucional usa DocumentClassifier batch, NO /document/process/institutional
3. OnBase requiere bearer token (no es anónimo)