> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Descripción general de la API de System Facts

> Qué registra System Facts, los cuatro pasos para integrar un producer y las convenciones que comparten todas las operaciones: tenant, idempotencia, paginación, sensibilidad y errores.

System Facts es el registro compartido de lo que pasó en tus flujos de negocio. Cada servicio que participa en un flujo, llamado producer, envía un hecho inmutable cuando ocurre un momento de negocio. Se hace un pedido. Se liquida un pago.

System Facts revisa cada hecho contra el contrato que registró su producer, lo almacena una sola vez y une en un solo flujo los hechos que comparten una referencia. Así preguntas qué pasó con el pedido `ORD-2026-000123` y recibes todos los hechos de ese flujo, de todos los producers, en una sola respuesta.

Un hecho almacenado nunca cambia. System Facts registra y correlaciona. No edita el historial.

## Conceptos

***

| Término | Significado |
| :- | :- |
| Producer | Un servicio que envía hechos, como `checkout-api` o `payments-api`. |
| Namespace | El nombre separado por puntos bajo el que un producer envía sus hechos, como `acme.checkout`. El primer servicio que registra un contrato para un producer y un namespace pasa a ser su dueño. |
| Tipo de hecho | El nombre de un tipo de momento de negocio, como `checkout.order_placed`. |
| Contrato | Una versión semántica de un tipo de hecho, con el JSON Schema de su payload y las referencias que llevan sus hechos. |
| Tipo de referencia | Un tipo con nombre de identificador de negocio, como `acme.order_id`. Lo registras una vez, con su ámbito, correlación, sensibilidad y la configuración searchable. |
| Referencia | Un identificador que lleva un hecho: un tipo de referencia, un valor y un ámbito. Por ejemplo, `acme.order_id` `ORD-2026-000123` con ámbito `storeId: store-sp-01`. |
| Subject | La entidad de negocio sobre la que trata un hecho, dada como un tipo y un id, como `checkout.order` `ORD-2026-000123`. |
| Hecho | Un registro inmutable de que ocurrió un momento de negocio. Se envía como un envelope con su subject, sus referencias y su payload (`data`). |
| Flujo | El grupo de hechos unidos por sus referencias. Un `flowAggregationId` lo identifica. |

Un tipo de referencia con `correlation: exact` une su hecho con todo hecho que lleve la misma referencia. Cuando un hecho une dos flujos, estos se fusionan en uno. El id del flujo absorbido sigue resolviendo hacia el flujo que sobrevive.

Un tipo de referencia registrado con `searchable: true` puede listar todo hecho que lo lleve.

## Integra en cuatro pasos

***

**1. Registra los tipos de referencia**

Registra cada tipo de identificador que llevan tus hechos con `PUT /v1/reference-types/{type}`, como `acme.order_id` y `acme.payment_id`. Hazlo desde tu pipeline de despliegue, antes de que cualquier contrato use el tipo.

```bash theme={null}
curl -X PUT "$SYSTEM_FACTS_URL/v1/reference-types/acme.order_id" \
  -H "Authorization: Bearer $SYSTEM_FACTS_BEARER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": ["storeId"],
    "sensitivity": "none",
    "correlation": "exact",
    "searchable": true,
    "description": "Order number assigned by the checkout service, unique within a store"
  }'
```

**2. Registra una versión de contrato**

Registra una versión de cada tipo de hecho con `PUT /v1/contracts/{producer}/{namespace}/{type}/{schemaVersion}`. Hazlo desde tu pipeline de despliegue, antes del rollout del producer. System Facts acepta hechos solo después de que el registro tiene éxito.

**3. Envía hechos**

Envía un envelope por momento de negocio con `POST /v1/facts`. Usa la credencial de servicio del producer para el tenant.

```bash theme={null}
curl -X POST "$SYSTEM_FACTS_URL/v1/facts" \
  -H "Authorization: Bearer $SYSTEM_FACTS_BEARER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "envelopeVersion": 1,
    "factId": "01a15493-ba10-7b21-9d44-3c1f8e2a9b01",
    "producer": "checkout-api",
    "namespace": "acme.checkout",
    "type": "checkout.order_placed",
    "schemaVersion": "1.0.0",
    "occurredAt": "2026-10-19T14:32:10Z",
    "subject": { "type": "checkout.order", "id": "ORD-2026-000123" },
    "references": [
      {
        "type": "acme.order_id",
        "value": "ORD-2026-000123",
        "scope": { "storeId": "store-sp-01" }
      }
    ],
    "data": { "amount": "129.90", "currency": "BRL" }
  }'
```

Un primer envío responde `201`.

```json theme={null}
{
  "factId": "01a15493-ba10-7b21-9d44-3c1f8e2a9b01",
  "producer": "checkout-api",
  "flowAggregationId": "01a15493-bdf8-7c55-b0e2-6f4a1d9e7c33",
  "duplicate": false,
  "ingestedAt": "2026-10-19T14:32:11Z"
}
```

**4. Lee los flujos**

Lee un flujo por su id con `GET /v1/flows/{flowAggregationId}`. Encuentra el único flujo de una referencia con `GET /v1/flows/by-reference`. Lista todo hecho que lleve una referencia searchable con `GET /v1/flows`.

```bash theme={null}
curl -G "$SYSTEM_FACTS_URL/v1/flows/by-reference" \
  -H "Authorization: Bearer $SYSTEM_FACTS_BEARER_TOKEN" \
  --data-urlencode "referenceType=acme.order_id" \
  --data-urlencode "referenceValue=ORD-2026-000123" \
  --data-urlencode "storeId=store-sp-01"
```

Toda escritura es idempotente, así que un producer puede reenviar después de un timeout.

## Autenticación y permisos

***

Toda solicitud, excepto los health probes públicos, envía `Authorization: Bearer <token>`. Los hechos y los flujos pertenecen al tenant del token. Los catálogos de tipos de referencia y de contratos los comparten todos los tenants del despliegue.

| Operación | Permiso |
| :- | :- |
| `GET /v1/reference-types`, `GET /v1/reference-types/{type}`, `GET /v1/contracts`, `GET /v1/contracts/{producer}/{namespace}/{type}`, `GET /v1/contracts/{producer}/{namespace}/{type}/{schemaVersion}` | `contracts:read` |
| `PUT /v1/reference-types/{type}`, `PUT /v1/contracts/{producer}/{namespace}/{type}/{schemaVersion}` | `contracts:read`, `contracts:write` y `catalog:reserved`. Todo nombre de catálogo está bajo un prefijo reservado. |
| `POST /v1/contracts/{producer}/{namespace}/{type}/{schemaVersion}/deprecate` | `contracts:read` y `contracts:write`, más `catalog:deprecate` para una versión cuyo namespace no posees |
| `POST /v1/facts` | `facts:read` y `facts:write` |
| `GET /v1/flows/{flowAggregationId}`, `GET /v1/flows/by-reference`, `GET /v1/flows` | `facts:read`. Con `facts:reveal`, los valores encrypted vuelven en texto claro. |

Un permiso ausente responde `403` `SF-0014`. Un token ausente o inválido responde `401` `SF-0013`.

## Convenciones

***

* **Tenant.** El servicio siempre toma el tenant del token. Nunca lee un tenant de una ruta, de un parámetro de consulta ni de un cuerpo.
* **Escrituras idempotentes.** Un primer registro o envío responde `201`. La misma solicitud de nuevo responde `200` y no cambia nada. El envío de un hecho agrega `duplicate: true`.
* **Inmutabilidad.** Una versión de contrato, un tipo de referencia y un hecho nunca cambian. Contenido distinto bajo la misma identidad responde `409`. Un tipo de referencia puede ganar un `mask` de visualización una vez.
* **Paginación.** Una lista responde una página y un `nextCursor`. Envíalo de vuelta como el parámetro de cursor de la página que quieres. Trátalo como opaco. Detente cuando se omita.
* **Timestamps.** RFC 3339 en UTC, como `2026-10-19T14:32:10Z`.
* **Tamaño.** Un envelope de hecho pesa como máximo 256 KiB por defecto. Uno más grande responde `413` `SF-0012`.
* **Nombres.** El primer segmento separado por punto de todo nombre de namespace y de tipo de referencia debe ser uno de los prefijos reservados del despliegue. El valor por defecto es `lerian`. Estas páginas usan `acme`.

## Sensibilidad y valores protegidos

***

La `sensitivity` de un tipo de referencia decide cómo muestran sus valores las lecturas. Un contrato puede marcar campos del payload de la misma forma con `x-sensitivity`.

| Sensibilidad | Qué devuelve una lectura |
| :- | :- |
| `none` | El valor tal como se envió. |
| `masked` | `****` más los últimos 4 caracteres de un valor de 12 o más caracteres, y solo `****` en los demás casos. Nunca el valor en texto claro. |
| `hashed` | El digest con clave `hmac-sha256:v1:<hex>`. Nunca el valor en texto claro. |
| `encrypted` | Almacenado sellado con AES-256-GCM. Se devuelve enmascarado, o en texto claro para un llamador que tiene `facts:reveal`. |

Con `mask: document`, un valor masked muestra `***.456.789-**` para 11 dígitos y `**.345.678/0001-**` para 14 dígitos. System Facts rechaza cualquier otra cantidad de dígitos al enviar.

Toda clase correlaciona exactamente como `none`, porque la comparación parte del valor en texto claro. Todo digest almacenado lleva clave. Nunca es un hash simple.

Un valor protegido vuelve con `protected: true`, y los campos protegidos del payload aparecen en `protectedFields`. Para encontrar un flujo por una referencia protegida, envía siempre el valor en texto claro. System Facts calcula su digest y lo compara con el digest almacenado.

## Errores

***

Todo error es `application/problem+json` (RFC 9457) con un `code` estable.

```json theme={null}
{
  "code": "SF-0009",
  "detail": "Verify the identifier: an identifier absorbed by a merge still resolves, an unknown one does not.",
  "instance": "0199c1f07a3e7b219d443c1f8e2a9b01",
  "status": 404,
  "title": "Not Found",
  "type": "https://errors.lerian.studio/v1/SF-0009"
}
```

> **[Lista de errores](/es/reference/platform/system-facts/system-facts-error-list)**
>
> Consulta cada código, cuándo lo responde el servicio y si conviene reintentar.

> **[Registrar una versión de contrato](/es/reference/platform/system-facts/register-a-contract-version)**
>
> Empieza por la operación que todo producer ejecuta primero.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.