API de Integraciones

La API REST de Kordia (/api/v1) y MCP (/mcp) comparten operaciones y reglas de dominio. REST requiere Starter o Pro; MCP es exclusivo de Pro. La suscripción debe estar en estado active, comprobado en cada petición, y la API key debe tener los scopes necesarios.

Especificación: GET /api/openapi.json.

Referencia por área

Cada referencia indica campos requeridos/opcionales, tipos, envelopes y códigos de respuesta. Los ejemplos HTTP usan IDs ilustrativos: sustitúyelos por los de tu organización y añade Bearer. Envía JSON con Content-Type: application/json. Los IDs son enteros positivos (REST también admite cadenas enteras); fechas YYYY-MM-DD, timestamps ISO 8601 y costes como decimal string, por ejemplo "52.50", no números binarios en coma flotante.

Alcance operativo

Área Operaciones
Proyectos Listar, consultar, crear, actualizar, archivar, reactivar y borrar
Recursos, contratos y etiquetas Listar, consultar, crear, actualizar y borrar
Asignaciones Consultar, planificar, crear, actualizar y borrar
Informes Horas mensuales, disponibilidad y desglose por etiquetas
Organización Consultar y actualizar nombre y horas anuales por defecto
Miembros Listar miembros/invitaciones, invitar, cambiar roles, retirar y revocar

La cuenta personal, checkout/facturación y eliminación de organizaciones permanecen en la UI. No se promete paridad literal con toda la interfaz.

Rutas

Todas llevan el prefijo /api/v1.

Método Ruta
GET / POST /projects, /resources, /contracts, /tags, /assignments
GET / PATCH / PUT / DELETE Las mismas colecciones con /:id
POST /projects/:id/archive, /projects/:id/unarchive
POST /planning/assignments, /contracts/preview, /contracts/:id/preview
GET /reports/:kind/:id, /reports/availability, /organization, /members
PATCH /organization, /members/:id
POST /invitations
DELETE /members/:id, /invitations/:id

Flujo recomendado

  1. Un administrador crea una clave desde API keys, seleccionando los scopes mínimos.
  2. Importa proyectos y recursos; añade contratos para disponer de capacidad.
  3. Usa /planning/assignments con project_id, start_date, end_date y daily_hours o total_hours. Sin resource_id busca candidatos por disponibilidad (query, tag_ids, limit y after_id opcionales). Continúa con next_after_id como after_id, incluso si una página devuelve candidates vacío. Con resource_id, sin filtros de candidatos, devuelve el reparto calculado sin guardar. No es un optimizador global.
  4. Inspecciona la desviación del preview antes de guardar con POST /assignments, por ejemplo {"project_id":10,"resource_id":7,"start_date":"2026-06-01","end_date":"2026-06-30","total_hours":80}. Puede devolver varios segmentos en data.assignments. En modo total, preview y escritura incluyen requested_total_hours, planned_total_hours, deviation_hours, tolerance_hours y exact; total_hours es el total planificado. El planificador compartido con la UI admite tolerancia de 0.01 horas sin superar el total solicitado. La disponibilidad se revalida al guardar; revisa también el resultado de escritura.
  5. Antes de cambiar un contrato, llama POST /contracts/5/preview con {"operation":"update","daily_hours":4}. Revisa data.conflicts; para resolverlos explícitamente usa PATCH /contracts/5 con {"daily_hours":4,"conflict_policy":"resolve","entry_ids":[42]}, sustituyendo IDs por conflictos actuales. El valor por defecto es reject; los bloqueos de proyectos archivados no se eluden.
  6. Consulta GET /reports/project_hours/10?year=2026. Otros tipos: resource_hours, availability (ID de recurso opcional; sin ID incluye toda la organización) y tag_breakdown (ID de proyecto). Usa year o from/to, no ambos.

Se conservan las validaciones de capacidad contractual, solapes, ventanas de proyecto, costes, archivos y límites del plan. Ajustes de organización y miembros requieren un creador de clave que siga siendo administrador, además del scope.

Respuestas e importaciones repetibles

Los éxitos devuelven data; las listas están paginadas:

{"data":[],"meta":{"limit":50,"offset":0,"total":0}}

Usa limit (1–100) y offset. Proyectos y recursos aceptan external_id opcional, único por organización y entidad; puedes consultarlo con GET /resources?external_id=employee-456. No es un upsert ni idempotencia automática. No reintentes mutaciones a ciegas tras un timeout: consulta primero el estado.