Skip to main content
Todas las rutas están bajo la base URL (/api/v1) y requieren autenticación. Las lecturas son de miembro del workspace; las escrituras requieren el scope work:write por OAuth; purge es solo owner/admin. Las lecturas son active-only, acotadas y brief por defecto — los objetos archived solo aparecen con un opt-in explícito. Ver Collections para el modelo.

Collections

Cuerpo de creación (CreateCollectionDto): name (obligatorio), archetype (obligatorio, uno de pipeline, analysis, content), record_schema, views, criterion_rel_slugs, distill_policy, owner_clerk_id. El update acepta name, record_schema, views, criterion_rel_slugs, distill_policy — un status de archived devuelve 409 y nombra la ruta de ciclo de vida que usar.

Records

Ruta base /workspaces/:slug/collections/:id. Cuerpo de record (CreateRecordDto / UpdateRecordDto): fields, status, field_meta, entity_id, y drifted en el update. El status de un record se valida contra los stages de la collection. entity_id es una propiedad top-level del record, nunca un campo dentro de fields (pasa "" en update para limpiar el link). Una transición a un stage terminal dispara el distill_policy y puede adjuntar un context_outcome (created · already_exists · skipped · failed) al record — best-effort, nunca bloquea la escritura.

Entities

Cuerpo de upsert (UpsertEntityDto): kind (obligatorio), name (obligatorio), dedup_key, attributes. El upsert es idempotente sobre (kind, dedup_key) — re-upsertar el mismo par mergea name/attributes en vez de crear un duplicado.

Paginación y errores

list y search de collections paginan por keyset cursor (limit 1–50, default 20; cursor opaco del nextCursor previo); list es dual-shape por back-compat — bare array cuando no hay param de paging/filter, el sobre {items, nextCursor} en caso contrario. list y retrieve de records paginan por keyset (limit 1–100, default 25; keyset sobre created_at, id). La lista de entities es un array acotado (sin cursor). Un status inválido (fuera de los stages de la collection) o un archetype inválido, o un campo de cuerpo desconocido, devuelve 400 VALIDATION_FAILED. Un fields JSON malformado en retrieve se ignora silenciosamente, nunca erroriza. Ver errores para el sobre.

Ciclo de vida: archive y purge

  • POST .../:id/archive retira una collection activa. POST .../:id/restore reviven una collection archived a active. Ambos incrementan version y se auditan. Una collection archived es inmutablePATCH, las escrituras de records y retrieve devuelven 409 PROTECTED_RESOURCE.
  • DELETE .../:id?dry_run=true previsualiza el impacto (distilled_notes_preserved cuenta las distilled Notes que sobreviven al borrado; entity_links_removed cuenta los record links rotos). DELETE .../:id?expected_version=<n> ejecuta el purge con compare-and-set; un expected_version que no coincide devuelve 409 VERSION_CONFLICT. Solo owner/admin, auditado, idempotente — un reintento tras el purge devuelve already_absent.
El safe delete de records sigue la misma forma: DELETE .../records/:recordId solo elimina de una collection no archived; ?dry_run=true previsualiza el Entity link removido y las distilled Notes preservadas (sobreviven al borrado, no se re-evalúan). El delete está gateado por membresía del workspace (no owner/admin), auditado, idempotente — un reintento tras el borrado devuelve already_absent.

Relacionado