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
| Servicio | Uso | Scope OAuth2 | Nota |
UploadDocument | Upload, estado, eliminación | UploadDocument | Principal de ingesta |
DocumentClassifier | DocumentGroups + batch | DocumentClassifier | Visibilidad restringida |
ClientAssistant | Chat con asistentes | ClientAssistant | Preguntas RAG |
OnBase | Navegación de archivos | OnBase | Requiere 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
| Servicio | Scope |
| UploadDocument | api://FA-<env>-AIUniandes-UploadDocument/.default |
| DocumentClassifier | api://FA-<env>-AIUniandes-DocumentClassifier/.default |
| ClientAssistant | api://FA-<env>-AIUniandes-ClientAssistant/.default |
| OnBase | api://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
| Campo | Tipo | Valor | Requerido |
file | binario | Contenido del archivo | Sí |
source | texto | CONTEXT_ASSISTANT | Sí |
application_id | texto | UUID del asistente | No |
conversation_id | texto | UUID de conversación | No |
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
| Estado | Significado | Acción |
READY | Documento listo | Fin exitoso |
PROCESSED | Procesamiento completado | Fin exitoso |
ERROR | Error en procesamiento | Revisar logs |
FAILED | Fallo irrecuperable | Reintentar |
DELETED | Eliminado | N/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
| Alias | model | model_label |
| gpt-5 | GPT_5_CHAT_UNIANDES | Open AI gpt-5-chat |
| gpt-4.1 | GPT_4_1_CHAT_UNIANDES | Open AI gpt-4.1-chat |
| gpt-4o | GPT_4o_CHAT_UNIANDES | Open AI gpt-4o-chat |
| deepseek | DEEPSEEK_R1_CHAT_UNIANDES | DeepSeek 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
| Campo | Tipo | Descripción |
answer | string | Texto de respuesta |
id | UUID | ID del mensaje |
idConversation | UUID | Reutilizar para el hilo |
keyWords | array | Palabras clave |
links | array | Referencias 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 Excel | Origen | Transformación |
source | — | Fijo: ONBASE |
document_onbase_id | file_id | Directo |
name | name | Directo |
typology | document_type | Directo |
category | path | Directo |
visibility | visibility | CLASSIFIED → RESTRICTED |
action | — | Fijo: 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}
| Estado | Terminal |
Completed | Sí |
Failed | Sí |
Running | No (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 APIM | Endpoints |
| Ingesta asistentes | upload assistant, process, status, delete |
| Chat asistentes | /ai-assistant/chat/{id} |
| Ingesta institucional | upload 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)