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

# Changelog

> Latest updates and improvements to gu1 documentation — covering new endpoints, dashboard features, and bug fixes, with examples for changelog use cases.

***

***

***

***

<Update label="2026-08-02" description="Transaction batch: skip invalid entity refs + failures.csv in S3" tags={["Transactions", "Batch", "API"]}>
  ## Row error policy and S3 artifacts for transaction batch

  * **`batchErrorHandling=rollback_all`** is the **default** (UI + multipart upload when omitted): aborts the file on invalid refs/amounts or insert failures; detail goes to **`failures.csv`** (S3), without giant jsonb arrays.
  * Clients can choose **`continue_collect_errors`** (skip invalid rows and create valid ones) or **`stop_keep_success`**.
  * The error-policy selector is also available on **non-mapper** imports (transactions and entities).
  * Failures CSV columns: `external_id,code,error,role,identifier_type,value`.
  * New **`GET /batch-import/jobs/{jobId}/payload`**: download the processed `payload.json` when stored (authenticated attachment).
  * **Alignment:** user-event and entity batch jobs now follow the same S3-first failures model as transactions (`item_failures` / terminal `item_results` cleared; JSON samples hydrate from CSV). Entity kind in responses is **`entity_batch`**; **`entity_automatic`** remains an accepted input alias.

  See [Batch import failure codes](/en/api-reference/bulk-imports/batch-import-failure-codes), [Transaction batch failures](/en/api-reference/bulk-imports/get-transaction-batch-failures), and [Download batch job payload](/en/api-reference/bulk-imports/get-batch-job-payload).
</Update>

<Update label="2026-07-31" description="Filter transactions by their latest rules evaluation date" tags={["Transactions", "Rules"]}>
  ## Latest rules evaluation date filter

  **`GET /transactions`** now accepts the optional inclusive ISO timestamp filters
  `lastRiskEvaluationFrom` and `lastRiskEvaluationTo`. They can be combined to select
  transactions whose latest successful rules evaluation falls within a date range.
  Transactions evaluated before this field existed are matched using their risk analysis
  history, and list items now return `lastRiskEvaluationAt`.

  See [List transactions](/en/api-reference/transactions/list).
</Update>

<Update label="2026-07-31" description="Legacy entity webhooks now include score and document number" tags={["Webhooks", "Entities"]}>
  ## Additional fields in legacy flat entity webhooks

  Legacy flat entity webhook payloads now include the additive fields `riskScore` and
  `documentNumber`. Existing status values and mappings remain unchanged.

  See [Entity webhook events](/en/webhooks/events/entity-events).
</Update>

<Update label="2026-07-31" description="Download which transactions were skipped as duplicates" tags={["Transactions", "Batch"]}>
  ## Skipped rows report for transaction batches

  New endpoint **`GET /batch-import/transaction-jobs/{jobId}/skips.csv`** lists the transactions a batch did not insert because the `externalId` already existed (columns `external_id,reason`). Until now `skipped` was only a counter, which made a duplicate re-upload look like a silent failure.

  * Available for jobs run with the default `skipDuplicates=true`; with `skipDuplicates=false` duplicates are resolved by the database and only counted, so the endpoint returns `SKIPS_NOT_AVAILABLE`.
  * Jobs finished before this release have no stored report (`SKIPS_NOT_AVAILABLE`).
  * Also available as a download button in the bulk imports history.

  See [Transaction batch failures](/en/api-reference/bulk-imports/get-transaction-batch-failures).
</Update>

<Update label="2026-07-24" description="Bulk: apply declared relationships when entity already exists" tags={["Entities", "Batch"]}>
  ## Declared relationships on duplicate `tax_id` (bulk)

  In **manual** bulk import, when a row’s `tax_id` already exists and creation is skipped, Gu1 still applies that row’s declared `relationships` / CSV `related_*` columns (same as **automatic** create). Existing edges (same source → target + type) are skipped idempotently.

  See [Import entities (bulk)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-07-23" description="Declarative relationships on entity create + bulk import" tags={["Entities", "API", "Batch"]}>
  ## Link to existing entities on create and bulk import

  You can declare relationships to entities that **already exist** (`relatedEntityId` / `relatedTaxId` / `relatedExternalId` + `relationshipType` + `role`) without relying on enrichment `depth`:

  * **`POST /entities`** and **`POST /entities/automatic`**: optional `relationships[]` body (max 10).
  * **Platform bulk CSV**: columns `related_tax_id` / `related_external_id` / `related_entity_id`, `relationship_type`, `relationship_role`, `relationship_as_source` (one relationship per row).
  * Missing counterpart → **`RELATED_ENTITY_NOT_FOUND`** and the entity is **not** created.

  See [Create entity](/en/api-reference/entities/create), [Create automatically](/en/api-reference/entities/create-automatic), and [Import entities (bulk)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-07-23" description="Security webhook: environment access changed" tags={["Webhooks", "Security", "IAM"]}>
  ## `security.member.environment_changed`

  When an admin updates a member's production/sandbox access from Teams (roster) in **one** assignment, Gu1 emits a single webhook instead of multiple grant/revoke events:

  * **Event:** `security.member.environment_changed`
  * **`context.fromAccess` / `context.toAccess`:** `"both"` | `"production"` | `"sandbox"` | `"none"`
  * **`changes.environmentAccess`:** `{ previous, current }` with the same values

  Existing `security.member.environment_granted` / `.environment_revoked` remain for single-environment grant/revoke flows.

  See [Security webhook events](/en/webhooks/events/security-events).
</Update>

<Update label="2026-07-22" description="linkEntityStrict + soft-link without breaking batch defaults" tags={["Transactions", "API", "Batch"]}>
  ## Entity link: soft-link always, strict default unchanged for batch

  Transaction create / batch **always tries to auto-link** when a match exists (entityId → externalId → taxId).

  * **Batch default (BC):** omitting flags stays **strict** — `validateExistingEntity` still defaults to **`true`**. Unresolved refs → **400** `INVALID_ENTITY_REFERENCES` (same as before for clients that omit the field).
  * **`linkEntityStrict=true`**: force hard-fail (body or query).
  * **`linkEntityStrict=false`**: force soft-link (do not fail if missing), even if `validateExistingEntity` would otherwise be true.
  * **`validateExistingEntity=false`**: soft-link (and still attaches when found — previously soft mode skipped linking on batch).

  Single `POST /transactions` keeps `validateExistingEntity` default **`false`**.

  See [Create batch](/en/api-reference/transactions/create-batch).
</Update>

<Update label="2026-07-13" description="Creation contract quota error code rename" tags={["API", "Billing"]}>
  ## Error code: `CREATION_CONTRACT_QUOTA_EXCEEDED`

  When an organization **contract creation quota** is exhausted (entities, transactions, user events), Gu1 APIs now return **`429`** with code **`CREATION_CONTRACT_QUOTA_EXCEEDED`** (replacing `CREATION_QUOTA_EXCEEDED`).

  * Same HTTP status and payload shape (`module`, `remainingTotal`, `periodKey`, `requested`).
  * Batch import row failures emit **`CREATION_CONTRACT_QUOTA_EXCEEDED`**; the old code remains accepted as a deprecated alias for historical `failures.csv`.

  See [Batch import failure codes](/en/api-reference/bulk-imports/batch-import-failure-codes).
</Update>

<Update label="2026-07-10" description="Entity taxId uniqueness across person and company" tags={["API", "Entities"]}>
  ## Tax ID uniqueness (org-wide)

  An active **`taxId`** (normalized alphanumeric) may belong to **only one** entity per organization, whether `person` or `company`.

  * **Same type** already exists → automatic creation **reuses** that entity (`alreadyExisted`).
  * **Other type** already holds the tax ID → **`409`** with code **`DUPLICATE_TAX_ID`** (no new row).
  * Applies to manual create, automatic create, tax ID PATCH, and soft-delete restore.
  * Historical duplicate rows are not deleted; new conflicting writes are blocked in app and via a database trigger.

  See [Create entity automatically](/en/api-reference/entities/create-automatic) and [Create entity](/en/api-reference/entities/create).
</Update>

<Update label="2026-07-08" description="addFieldToCustomList rule action" tags={["API", "Rules"]}>
  ## New rule action: `addFieldToCustomList`

  **Transaction**, **person**, and **company** rules may include `addFieldToCustomList`. On match, the engine extracts one or more fields from the evaluation context and appends them to tenant **custom lists** (`type: custom`, active, non-global).

  ```json theme={null}
  {
    "type": "addFieldToCustomList",
    "addFieldToCustomList": {
      "mappings": [
        { "fieldPath": "originTaxId", "listId": "uuid-list-123" },
        { "fieldPath": "metadata.phone", "listId": "uuid-list-456" }
      ],
      "reason": "Optional item reason"
    }
  }
  ```

  Empty values are skipped; duplicate `primaryValue` entries are ignored. Available on universal rule `POST`/`PUT` and in the Rule Builder.
</Update>

<Update label="2026-07-08" description="Entity creation list enforcement" tags={["API", "Entities"]}>
  ## Creation blocklist (risk analysis settings)

  Organizations can configure **creation blocklist rules** in **Organization settings → Risk analysis**: map an entity field (e.g. `taxId`) to a custom list. If the value is found in the list, **entity creation is blocked**: the request fails with **`422`** and error code **`ENTITY_CREATION_LIST_BLOCK`** (`details` include `ruleId`, `listId`, `fieldPath`, `scope`, `matchedValue`). The blocked attempt is recorded in the audit log as evidence.

  Applies to **`POST /entities`**, **`POST /entities/automatic`**, bulk import, upsert create path, and SDK auto-entity creation. Shareholder/UBO checks run during automatic creation when scope is configured; if a shareholder is blocked, the entities created in that automatic run are rolled back.
</Update>

<Update label="2026-07-03" description="PATCH /entities/{id}/attributes" tags={["API", "Entities"]}>
  ## Dedicated attributes update endpoint

  **`PATCH /entities/{id}/attributes`** — update only custom attributes without touching other entity fields.

  * **`mode: merge`** (default) — sent keys overwrite or create; omitted keys are **kept**
  * **`mode: replace`** — body `attributes` becomes the full map (`{}` clears all)
  * Nested category buckets supported on write (same as entity update)
  * Triggers **`entity.updated`** webhook and risk matrices with **`entity_updated`** trigger when configured

  See [Update entity attributes](/en/api-reference/entities/attributes-update).
</Update>

<Update label="2026-07-03" description="Entity attributes: verbatim storage + categories" tags={["API", "Entities"]}>
  ## Custom attributes stored verbatim (API)

  **Additive.** `attributes` are stored **exactly as sent** on create/update/upsert/automatic import paths — nested input is no longer flattened.

  * **Uncategorized:** scalar/array values at the root (e.g. `{ "phone": "..." }`) — unchanged.
  * **Categorized:** a top-level object groups its inner keys under that category (e.g. `{ "contact": { "phone": "..." } }`). The object key *is* the category; in the dashboard it renders as a category card.
  * **Read:** `GET` returns the same shape that was written (no flattening).
  * **Rules / webhooks:** read the stored shape — `attributes.phone` for flat, `attributes.contact.phone` for nested. Use identifier-safe category keys.

  See [Get entity](/en/api-reference/entities/get) and [Update entity](/en/api-reference/entities/update).
</Update>

<Update label="2026-07-03" description="Entity country activations API + webhook" tags={["API", "Webhooks", "Entities"]}>
  ## Per-merchant country activation (operational flag)

  **Additive.** Activate or deactivate supported countries per entity without changing entity profile data:

  * **`GET /entities/{id}/country-activations`** — lists AR, BR, CL, CO, MX, US; missing rows = `deactivated` (opt-in).
  * **`PATCH /entities/{id}/country-activations/{countryCode}`** — body `{ "status": "deactivated" | "activation_requested" | "activation_in_progress" | "activated" }`; requires `entities:edit`. Free-form transitions. Idempotent when status unchanged (no webhook).
  * **Webhook `entity.country_activation_changed`** — emitted on every real status change; includes `activeCountryCodes`, full `countries` snapshot, and per-country `timeline`; subscribe via existing webhook config.

  See [List country activations](/en/api-reference/entities/country-activations-list), [Update country activation](/en/api-reference/entities/country-activations-update), and [Entity webhook events](/en/webhooks/events/entity-events).
</Update>

<Update label="2026-07-01" description="Bulk import: user events error policy parity" tags={["API", "Bulk imports"]}>
  ## User event batch import — row error policy

  **Additive.** User event CSV imports now match entity and transaction batch behavior:

  * **`POST /batch-import/import/user-events`** accepts optional multipart field **`batchErrorHandling`**: `continue_collect_errors` (default), `rollback_all`, or `stop_keep_success`.
  * **`202`** responses include **`preflightFailures`** when invalid rows are skipped under continue policy.
  * **`POST /batch-import/validate-csv`** validates **each row** when the mapping target is **`user_event`** (`rowErrors`, `validRowCount`, `invalidRowCount`).

  See [Import user events](/en/api-reference/bulk-imports/import-user-events) and [Validate CSV](/en/api-reference/bulk-imports/validate-csv).
</Update>

<Update label="2026-07-01" description="Rules create: mandatory AI review + provenance" tags={["Rules", "API"]}>
  ## `POST /rules` — synchronous AI review on every create

  * New rules are always stored as **`in_progress`** with **`enabled: false`**; request `status` / `enabled` on create are ignored.
  * The response includes **`aiReview`** (verification summary) and may take several seconds.
  * Optional body **`creationProvenance`** records origin (`user`, `agent`, `import_json`, `template`, `bundle`, `api`) and optional agent chat ids.
  * AI review is audited but **not debited** from the AI token wallet.

  See [Create Rule](/en/api-reference/rules/create).
</Update>

<Update label="2026-06-26" description="Security webhooks: invitation context fields" tags={["Webhooks", "Security", "IAM"]}>
  ## `security.member.invited` / `security.member.created` — richer `payload.context`

  **Additive.** Invitation lifecycle webhooks now include correlation and access metadata in `payload.context`:

  * `invitationId` — correlate `invited` → `created`
  * `granularRoleIds`, `granularRoleIdsSandbox`
  * `includeProduction`, `includeSandbox`
  * `teamId`, `teamIdSandbox`
  * `hasEnvironmentAccess` — access flag for the org in the envelope
  * `environment` — `"production"` or `"sandbox"` for the envelope org
  * `invitedByUserId`, `acceptedVia` (on `created`)
  * `syncPartialFailure`, `syncErrorMessage` (on `created` when secondary setup did not fully complete)

  Existing fields are unchanged. See [Security webhook events](/en/webhooks/events/security-events).
</Update>

<Update label="2026-06-26" description="Batch import: poll job status by jobId" tags={["API", "Bulk imports"]}>
  ## Batch import job polling

  **Additive.** New canonical endpoint for integrators to poll a single batch import job without scanning paginated history.

  ### HTTP endpoints

  * `GET /batch-import/jobs/{jobId}` — direct lookup by job id across entity, transaction, and user-event imports. Returns `status`, counters (`totalItems`, `succeeded`, `failed`, `skipped`), timestamps, and optional `jobFailure` when the whole job aborted. Optional query `include=failures` returns the same JSON as the kind-specific failures endpoints (row-level `failures[]`).
  * `GET /batch-import/unified-history` — new optional query param **`jobId`** (exact match; 0 or 1 row). Unified history remains for listing recent jobs; use `GET /batch-import/jobs/{jobId}` for polling after upload.

  ### Recommended integrator flow

  Upload (`202` + `jobId`) → poll `GET /batch-import/jobs/{jobId}` every 2–5s until terminal status → fetch failures if needed.

  See [Get batch job status](/en/api-reference/bulk-imports/get-batch-job-status) and [Unified history](/en/api-reference/bulk-imports/list-unified-history).
</Update>

<Update label="2026-06-25" description="Holder CBU/CVU intelligence: exists + accounts-count + metrics" tags={["Marketplace", "API", "Rules"]}>
  ## Holder CBU/CVU intelligence (`ar_gueno_holder_intelligence_service`)

  **Additive.** Account totals endpoint is `accounts-count` (replaces pre-release `cbu-count`). Returns `snapshotDate`, `isNew`, `cbuCount`, `cvuCount`, and `totalAccounts`.

  ### HTTP endpoints

  * `GET /api/integration-services/ar_gueno_holder_intelligence_service/health` — service availability and corpus freshness (`status`, `corpusFreshnessDate`). **No billing.**
  * `GET /api/integration-services/ar_gueno_holder_intelligence_service/cuits/:cuit/exists` — corpus membership check. Returns `found` and `snapshotDate` (`null` when not found). Always HTTP `200` on success (including `found: false`). **No billing.**
  * `GET /api/integration-services/ar_gueno_holder_intelligence_service/cuits/:cuit/accounts-count` — CBU/CVU totals plus `isNew` and `snapshotDate`. **Billable per request** when priced.
  * `GET /api/integration-services/ar_gueno_holder_intelligence_service/cuits/:cuit/metrics` — densified incremental lookback (`lookback` 1–180 **or** `window` preset `w_1d`…`w_180d`). Optional query `date` (`YYYY-MM-DD`, inclusive window end). Returns stock aliases, deltas, `%`, variance, and acceleration. **Billable per request** when priced. Errors: `400` `LOOKBACK_REQUIRED` / `INVALID_LOOKBACK` / `INVALID_WINDOW` / `INVALID_DATE`, `404` `CUIT_NOT_FOUND`, `422` `INCOMPLETE_WINDOW` / `NO_INCREMENTAL_STATE`.

  ### Rules engine

  New condition fields under `services.holder_intelligence.*`: `found`, `snapshot_date`, `cbu_quantity`, `cvu_quantity`, `total_accounts`, and nested `metrics.*` with per-condition `holderIntelligenceLookbackDays` (1–180). On transaction rules the window ends on `transactedAt` by default. Metrics trigger a separate billable upstream fetch when referenced.

  See [Provider codes](/en/api-reference/integrations/provider-codes) and [Marketplace Services](/en/api-reference/services/overview) (per-endpoint reference).
</Update>

<Update label="2026-06-26" description="Marketplace Services documentation section" tags={["Docs", "Marketplace", "API"]}>
  ## Marketplace Services docs (en / es / pt)

  New sidebar section **Services** with overview, per-service guides, and one page per HTTP endpoint for `ar_gueno_holder_intelligence_service`. [Services overview](/en/api-reference/services/overview).
</Update>

<Update label="2026-06-24" description="KYC & biometric: entityTaxId / entityExternalId" tags={["KYC", "Biometric", "API", "Entities"]}>
  ## Entity identifiers beyond `entityId`

  **Additive — backward compatible.** Existing clients sending only `entityId` behave unchanged.

  ### Create (POST)

  * `POST /api/kyc/validations` — body accepts **`entityId`**, **`entityExternalId`**, or **`entityTaxId`** (exactly one required).
  * `POST /api/kyc/biometric/sessions` — same identifier options.

  Gu1 resolves `entityExternalId` / `entityTaxId` to the internal entity UUID. Returns **`404 NOT_FOUND`** if no persisted entity matches.

  ### Read (GET)

  * `GET /api/kyc/validations?entityTaxId=...` or `?entityExternalId=...` (mutually exclusive with `entityId`).
  * `GET /api/kyc/biometric/sessions?entityTaxId=...` or `?entityExternalId=...`
  * KYC: `GET /api/kyc/entities/by-tax-id/:taxId/current|validations|status` and `.../by-external-id/:externalId/...`
  * Biometric: `GET /api/kyc/biometric/entities/by-tax-id/:taxId/current` and `.../by-external-id/:externalId/current`

  ### Sandbox entity preview (GET only)

  * `GET /api/entities/by-tax-id/{taxId}` and `GET /api/entities?taxId=...` may return **`sandboxMock: true`** synthetic data for catalog test document numbers when no real row exists (`id: null`). Does **not** enable POST without creating a real entity.

  See [Create KYC validation](/en/use-cases/kyc/create-validation), [Embedded biometric session](/en/use-cases/kyc/embedded-biometric), and [Sandbox mock data](/en/use-cases/kyc/sandbox-mock-data).
</Update>

<Update label="2026-06-23" description="KYC & biometric create: blocking IDs on 409" tags={["KYC", "Biometric", "API"]}>
  ## Additive 409 responses for open sessions / validations

  **No breaking change** for clients that only read `error` and `message`. New optional fields on existing `409` codes:

  ### Embedded biometric — `POST /api/kyc/biometric/sessions`

  * While the latest session is `pending` or `in_progress`, create **always** returns **`409 ACTIVE_SESSION_EXISTS`** (never `201` with the same pending session).
  * Body includes **`activeSessionId`** for cancel: `POST .../sessions/{activeSessionId}/cancel`.

  ### KYC validation — `POST /api/kyc/validations`

  * While the entity has an open validation (`pending`, `in_progress`, `in_review`), create returns **`409 VALIDATION_IN_PROGRESS`**.
  * Body now also includes **`activeValidationId`** for cancel: `DELETE .../validations/{activeValidationId}/cancel`.

  See [Create KYC validation](/en/use-cases/kyc/create-validation) and [Embedded biometric session](/en/use-cases/kyc/embedded-biometric).
</Update>

<Update label="2026-06-20" description="GET transaction: optional rulesExecutionSummary on persisted" tags={["API", "Transactions", "Rules"]}>
  ## `includeRulesSummary` on single-transaction GET

  `GET /transactions/{id}` and `GET /transactions/external/{externalId}` accept an optional query parameter:

  * **`includeRulesSummary=full`** — Adds **`persisted.rulesExecutionSummary`** from the **latest** `risk_analysis_audits` row for that transaction. Rules are **not** re-executed on read.

  **Default (param omitted):** unchanged response — no `rulesExecutionSummary` on read. Use `full` only for detail views or debugging, not high-volume list polling.

  See [Get transaction](/en/api-reference/transactions/get) and [Rules execution summary](/en/api-reference/rules-execution-summary).
</Update>

<Update label="2026-06-19" description="Rules execution summary: transaction party entity status" tags={["API", "Rules", "Transactions"]}>
  ## Optional fields in `rulesExecutionSummary`

  When transaction rules use `updateEntityStatus` with origin or destination party entity status, the API may now include these **optional** fields (additive; existing clients unchanged):

  * **`rulesHit[].actions.originEntityStatus`** / **`destinationEntityStatus`** — configured on the matched rule.
  * **`actionsExecuted.originEntityStatus`** / **`destinationEntityStatus`** — final entity statuses applied in that run (alongside existing **`actionsExecuted.status`** for transaction status).

  Audit rule snapshots now retain the full configured action list (including deferred status actions) for UI and integrators.

  See [Rules Execution Summary](/en/api-reference/rules-execution-summary).
</Update>

<Update label="2026-06-19" description="Security webhooks: unified member + environments" tags={["Webhooks", "Security", "IAM"]}>
  ## `security.member.*` events (unified naming)

  All IAM events about people use the **`security.member.*`** prefix (no more `security.user.*`, `security.team.*`, or `security.channel.*`):

  * **Profile / password:** `security.member.profile_updated`, `.password_reset`, `.password_generated`
  * **Teams:** `security.member.team_added`, `.team_removed`, `.team_role_changed`
  * **Channels (child org):** `security.member.channel_granted`, `.channel_revoked`
  * **Environment access (production / sandbox):** `security.member.environment_granted`, `.environment_revoked` — use `context.environment` (`"production"` | `"sandbox"`)

  Team membership changes no longer emit misleading `security.role.assigned` / `security.role.updated` events.

  **Breaking:** if you subscribed to `security.user.password_*` or other legacy keys, migrate to the matching `security.member.*` keys.

  See [Security webhook events](/en/webhooks/events/security-events).
</Update>

<Update label="2026-06-19" description="Biometric current session endpoint" tags={["KYC", "Biometric", "API"]}>
  ## `GET /api/kyc/biometric/entities/:entityId/current`

  Aligned with KYC `GET /api/kyc/entities/:entityId/current`:

  * Returns the **latest biometric session** for the entity (by `createdAt`), **any status** (`pending`, `in_progress`, `approved`, `rejected`, …).
  * **`200` with `null`** when the entity has no biometric sessions (no longer `404`).
  * List endpoint `currentSessionId` still refers to the latest **`approved`** session only.

  **`409 ACTIVE_SESSION_EXISTS`** on create now includes **`activeSessionId`** so integrators can cancel the blocking session without an extra lookup.

  See [Current biometric session](/en/use-cases/kyc/current-biometric-session).
</Update>

<Update label="2026-06-18" description="Security & IAM webhook events" tags={["Webhooks", "Security", "IAM"]}>
  ## Security webhook events (`security.*`)

  New outbound webhook category for **Security / IAM** monitoring (SIEM integrations). Subscribe in **Webhooks → Configuration** to events such as:

  * **Auth:** `security.auth.login_succeeded`, `security.auth.logout`, `security.auth.login_failed`
  * **Members:** `security.member.invited`, `.created`, `.removed`, `.activated`, `.deactivated`
  * **Roles:** `security.role.created`, `.updated`, `.deleted`, `.assigned`, `.revoked`
  * **RBAC:** `security.rbac.granular_toggled`
  * **Password (admin):** `security.member.password_reset`, `security.member.password_generated` (formerly `security.user.password_*`)
  * **Settings:** `security.settings.updated` (sandbox, audited org security settings)

  Payload includes normalized `actionAt`, `actor`, `affectedUser`, `description`, `changes` (previous/current), and `context` (IP, user agent, scope).

  **Not covered:** Clerk self-service password change, MFA/SSO in Clerk, API-key auth.

  See [Security webhook events](/en/webhooks/events/security-events).
</Update>

<Update label="2026-06-18" description="Risk matrix watchFields + entity_updated runtime" tags={["Risk matrices", "Entities", "Transactions", "API"]}>
  ## Granular matrix triggers (`watchFields`)

  Risk matrix event triggers **`entity_updated`** (entities and KYT transaction updated) support optional **`watchFields`**: an array of rule-engine field paths (e.g. `email`, `phone`, `attributes.clientTypes`, `metadata.email`). When omitted or empty, **any** change on that event runs the matrix (backward compatible). When set, the matrix runs only if at least one listed path changed.

  Configure in the Risk Matrix editor (Triggers tab) or via API in `risk_matrices.triggers[]`.

  ## Entity update — `entity_updated` wired

  `PATCH /entities/{id}` (and by external ID / tax ID) now runs assigned matrices whose triggers include **`entity_updated`**, unless `skipRulesExecution: true`. The `entity.updated` webhook includes `rulesExecutionSummary` when rules ran or were skipped with a reason. See [Update entity](/en/api-reference/entities/update).

  Transaction `PATCH` with `executeRules=true` passes changed field paths to the same filter for transaction matrices.
</Update>

<Update label="2026-06-17" description="Bulk entity import — child enrichment policy" tags={["Entities", "Bulk import", "API"]}>
  ## Bulk automatic entity import — child enrichments & monitoring scope

  **`POST /batch-import/import/entities`** and JSON bulk automatic import accept two optional fields (automatic mode, `depth` > 0):

  * **`childEnrichmentPolicy`**: `all_active` (default), `by_root_type`, or `basic_only`.
    * **`by_root_type`**: company rows run all active enrichments on shareholders **except** `global_gueno_sanctions_enrichment`; person rows create related entities with **basic data only** from the root provider snapshot.
  * **`monitoringApplyToRelationships`**: when `false`, `monitoring` applies to main entities only (no watchlist on children). Default `true` when `depth` > 0 if omitted.

  The dashboard bulk entity import UI exposes the same controls. See [Import entities (bulk)](/en/api-reference/bulk-imports/import-entities#child-enrichments--monitoring).
</Update>

<Update label="2026-06-16" description="SDK pre-login events and remote config" tags={["Events", "SDK", "API"]}>
  ## Events — SDK session fields and pre-login

  `POST /events/user` now accepts two optional fields: **`sessionId`** (SDK session id, `sess_...`) and **`sdkSignals`** (structured SDK signals — integrity and behavioral flags, kept separate from `metadata`). Both persist on the event. **Omitting them keeps the previous behavior byte-for-byte.**

  For organizations with the SDK enabled, an event carrying **only a `sessionId`** (no `entityId`/`entityExternalId`/`taxId`) is now accepted and stored as an **anonymous pre-login event** instead of returning an error; it is linked to the entity later, on the first event that carries both `sessionId` and an entity identifier. Without the SDK enabled, an entity identifier is still required (same response as before).

  ## Events — new event types

  Three SDK event types were added: **`SESSION_STARTED`**, **`SESSION_IDENTIFIED`**, **`SCREEN_VIEW`**. Existing clients are unaffected.

  ## New endpoint — `GET /sdk/config`

  Returns the SDK remote config (signal toggles + transport defaults) plus the organization's `sdkEnabled` flag.

  See [Create User Event](/en/api-reference/events/create).
</Update>

<Update label="2026-06-15" description="Enrichment errors and tax ID validation" tags={["Enrichment", "Entities", "API"]}>
  ## Marketplace enrichment — structured errors

  `POST /integration-execution/marketplace/enrichment` now returns richer per-integration `error` objects: optional `category`, `retryable`, and `statusCode` alongside `code` and `message`. Codes distinguish configuration issues (integration not enabled), timeouts, provider HTTP failures, and validation errors.

  ## Automatic / bulk entity creation — tax ID strictness

  `taxId` on automatic and bulk creation must be **only** the fiscal identifier. Values merged with spreadsheet columns (e.g. CNPJ plus business segment text) are rejected with `INVALID_TAX_ID`.

  ## Transactions — optional `exchangeRate` fallback

  `POST /transactions` and batch create accept optional **`exchangeRate`** on each transaction. **Omitting it keeps the previous behavior** (automatic conversion via the currency service).

  Used **only** when automatic conversion is unavailable. Semantics: base-currency units per 1 unit of `currency`; normalized base amount = `amount × exchangeRate`. Sets `rateSource: client-provided`.

  **Non-convertible today (no automatic rate):** `WLD` (Worldcoin), `ETH` (Ethereum). Send `exchangeRate` for a normalized base-currency amount and FX-dependent rules.

  See [Create Transaction — Currency conversion](/en/api-reference/transactions/create#currency-conversion).
</Update>

<Update label="2026-06-11" description="Entities — refresh scope and preserve flags" tags={["Entities", "Enrichment", "API", "Docs"]}>
  ## `POST /entities/{entityId}/refresh` — unified scope and safe field sync

  New optional body fields (all backward compatible when omitted):

  * **`refreshScope`**: `basic_data` | `all_active` | `selected` (+ `providerCodes` when `selected`).
  * **`preserveName`**: `true` keeps the current display name; omitted = legacy sync from normalized `fullName`.
  * **`preserveEntityData`**: only with `refreshScope: "basic_data"` — `true` gap-fills `entityData`, `false` replaces; omitted = do not touch profile.

  `basic_data` always runs root-only (no shareholders), regardless of `depth`.

  See [Refresh Entity](/en/api-reference/entities/refresh). Existing Risk Matrix / integration payloads without these fields behave unchanged.
</Update>

<Update label="2026-06-11" description="KYC — cross-entity duplicate warning" tags={["KYC", "API", "Docs"]}>
  ## `GUENO_CROSS_ENTITY_DUPLICATED` warning

  When Gu1 resolves provider duplicate session/face references to **another entity** in the same organization (`metadata.kycCrossEntityDuplicates.matches`):

  * Appends warning **`GUENO_CROSS_ENTITY_DUPLICATED`** to session validation `warnings`.
  * If the provider mapped **`approved`**, Gu1 sets status to **`in_review`** (`metadata.guenoCrossEntityDuplicateEscalation`).
  * **Non-omittable:** cannot be sent in `omitWarnings` (400) and blocks omit auto-approve.

  Documented in [KYC warning risk codes](/en/use-cases/kyc/warning-risk-codes) and [`omitWarnings`](/en/use-cases/kyc/create-validation).
</Update>

<Update label="2026-06-11" description="KYC — Gu1 Biometric" tags={["KYC", "API", "Webhooks", "Docs"]}>
  ## Gu1 Biometric (`POST /api/kyc/biometric` and `/api/kyc/biometric/sessions`)

  Re-authentication after approved KYC: image upload check or **hosted UI** session (`sessionUrl`, `iframeAllow`, `hostedSessionId`, optional `webhookUrl`, org webhooks `biometric.session_*`, Gu1 **`status`** / `rejectionCode`). Marketplace product `global_gueno_biometric_kyc`. See [Biometric verification](/en/use-cases/kyc/biometric), [Biometric session](/en/use-cases/kyc/embedded-biometric), and [Biometric webhook events](/en/webhooks/events/biometric-events).
</Update>

<Update label="2026-06-10" description="KYC — decision dual array/object shape" tags={["KYC", "API", "Webhooks", "Docs"]}>
  ## `decision` always includes array + object feature pairs

  On persist (sync, webhook ingest, manual ingest), Gu1 **normalizes** `decision` so integrators can read either legacy singular keys or array keys interchangeably:

  * `id_verification` ↔ `id_verifications[0]`
  * `liveness` ↔ `liveness_checks[0]`
  * `face_match` ↔ `face_matches[0]`
  * `aml_screening` ↔ `aml_screenings[0]`
  * `ip_analysis` ↔ `ip_analyses[0]`

  When both shapes were present, **`array[0]` wins** and the singular object is synchronized. Applies to GET validation responses and KYC webhooks (`payload.decision`).

  Mintlify examples updated with **complete** `decision` payloads (no vendor branding; media as `kyc/...` keys). See [KYC webhook events](/en/webhooks/events/kyc-events#decision-object-payloaddecision).
</Update>

<Update label="2026-06-10" description="Risk matrix — rulesEngineConfig on analyze" tags={["Entities", "Risk Matrix", "API", "Docs"]}>
  ## Per-run rules engine config on `POST /entities/{entityId}/analyze`

  New optional body object **`rulesEngineConfig`** (all fields default **`false`**):

  * **`partialCoverage`:** with multiple assigned matrices, data coverage is validated **per matrix**; matrices without data are skipped (`matricesSkippedForCoverage` / `warnings` on partial success).
  * **`omitCoverage`:** skip data coverage gates entirely (main entity + shareholders). Precedence over `partialCoverage` when both are true.

  Default unchanged: union coverage blocks the whole run on any missing field (`422 INCOMPLETE_DATA_COVERAGE`).

  See [Analyze Entity](/en/api-reference/entities/analyze) and [Execute Risk Matrix](/en/api-reference/risk-matrix/execute-risk-matrix).
</Update>

<Update label="2026-06-09" description="KYC — extractedData.ejemplar (Argentine DNI)" tags={["KYC", "API", "Docs"]}>
  ## `ejemplar` in extractedData

  Argentine DNI verifications can include **`extractedData.ejemplar`** (`A`–`D`) on KYC validations and ID Verification audit records (GET, sync, webhooks).

  With **`doubleCheckRenaper: true`**, **`comparisonResults.ejemplar`** compares OCR vs RENAPER; mismatch adds **`RENAPER_EJEMPLAR_NOT_MATCH`** to **`warnings`**.

  See [extractedData fields](/en/use-cases/kyc/id-verification#extracteddata-fields) and [RENAPER double-check](/en/use-cases/kyc/create-validation#renaper-double-check-argentina).
</Update>

<Update label="2026-06-05" description="KYC — RENAPER flow and manual review" tags={["KYC", "API", "Docs"]}>
  ## RENAPER double-check on KYC validations

  With `doubleCheckRenaper: true`, `metadata.responseDoubleChecks.renaper` includes **`comparisonResults`**, **`renaperBiometric`** (when applicable), and RENAPER codes in **`warnings`** (e.g. `RENAPER_TRAMITE_ID_NOT_MATCH`, `RENAPER_EXPIRY_NOT_MATCH`) **without replacing** OCR KYC verification warnings.

  **Enforcement (auto-reject):** only when OCR KYC verification returns status **`approved`**. On **`in_review`** and **`rejected`** the check is informational and stores registry data. **`POST /api/kyc/validations/{id}/approve`** from `in_review` does **not** re-run RENAPER.

  See [Create KYC validation](/en/use-cases/kyc/create-validation#when-renaper-enforcement-applies-automatic-rejection) and [Approve validation](/en/use-cases/kyc/approve-validation).
</Update>

<Update label="2026-06-04" description="Marketplace — checks removed, enrichments only" tags={["Entities", "Enrichment", "API", "Docs"]}>
  ## Marketplace `*_check` product removed

  * **Removed:** all `*_check` provider codes, `POST /integration-execution/marketplace/check`, rules triggers/actions `check_completed` / `execute_check`, and RBAC permissions `checks:read` / `checks:execute`.
  * **Use instead:** matching `*_enrichment` codes with [Execute enrichment](/en/api-reference/enrichment/execute-by-id).
  * **Backward compat:** legacy create/import payloads with `checks`, `executeAllActiveChecks`, or `*_check` inside `autoExecuteIntegrations.enrichments` are **silently ignored** at parse time.

  See [Provider codes](/en/api-reference/integrations/provider-codes), [Create entity](/en/api-reference/entities/create), and [Create automatically](/en/api-reference/entities/create-automatic).
</Update>

<Update label="2026-06-04" description="Bulk imports — failure codes + JSON failures" tags={["Bulk imports", "API", "Docs"]}>
  ## Stable batch failure codes and JSON endpoints

  * **Row failures** now include stable **`code`** + **`message`** (catalog: [Failure codes](/en/api-reference/bulk-imports/batch-import-failure-codes)). CSV adds a `code` column (`external_id,code,error` / `row_key,code,error` / entity `…,code,error_message`).
  * **New JSON endpoints:** `GET /batch-import/transaction-jobs/{jobId}/failures`, `GET /batch-import/user-event-jobs/{jobId}/failures`, `GET /batch-import/entity-jobs/{jobId}/failures` — include `failures[]`, optional `jobFailure` for whole-job errors, entity `skips[]`, `truncated` / `failuresTotal` (max 500 stored).
  * **CSV download:** same routes with `.csv` suffix (`failures.csv`).
  * Legacy rows with only free-text `error` are normalized on read when possible.
</Update>

<Update label="2026-06-04" description="Entities — PATCH riskMatrixIds" tags={["Entities", "API", "Docs"]}>
  ## Assign risk matrices on entity update

  * **`PATCH /entities/{id}`** (and **`PATCH /entities/by-external-id/{externalId}`**, **`PATCH /entities/by-tax-id/{taxId}`**): document **`riskMatrixIds`** (`string[]`) and **`riskMatrixId`** (`string | string[] | null`) — same normalization as create. Assigns matrices on the entity; does **not** run the rules engine (use [Analyze entity](/en/api-reference/entities/analyze) or lifecycle triggers).
  * Mintlify updated in `/en/`, `/es/`, `/pt/` on [Update entity](/en/api-reference/entities/update) and [Update by external ID](/en/api-reference/entities/update-by-external-id).
</Update>

<Update label="2026-06-03" description="Transactions — configRulesExecution.notifications" tags={["Transactions", "Rules", "API", "Docs"]}>
  ## `configRulesExecution` on create transaction

  * **`POST /transactions`**: optional body object **`configRulesExecution`** with **`notifications`** (`boolean`). When `false`, gu1 skips **in-app** notifications from rules evaluation (risk matrix / status). **`createAlert`** actions and investigations are unchanged.
  * **Default:** omitting the object keeps prior behavior for most orgs (`notifications` effectively `true`). **Paytime prod** (`3bc1f621-27d4-423e-9d64-86680bec2388`) defaults to **`notifications: false`** when omitted.
  * **Legacy KYT** `POST /legacy/kyt/verifyTransaction`: same field on the Gu2 body; Paytime prod default **`notifications: false`** when omitted (normalized before create).
  * Applies to **sync and async** rules (`asyncRules`).

  See [Create transaction](/en/api-reference/transactions/create). Parity in `/es/` and `/pt/`.
</Update>

<Update label="2026-06-02" description="Transactions — canonical entity denormalization on link" tags={["Transactions", "API", "Docs"]}>
  ## `POST /transactions` and batch create — linked counterparty fields

  When origin or destination is **linked** to a person/company (`originEntityId` / auto-link by external or tax id), gu1 **always overwrites** denormalized columns from the entity row before insert:

  * `originTaxId` / `destinationTaxId` ← `entities.tax_id`
  * `originExternalId` / `destinationExternalId` ← `entities.external_id`

  Client-sent values for those fields are **not kept** if they differ from the linked entity. This aligns transaction monitoring rules with user events stored under the same entity identifiers.

  Documented in [Create transaction](/en/api-reference/transactions/create#origin-entity-fields) and [Create batch](/en/api-reference/transactions/create-batch). Parity in `/es/` and `/pt/`.
</Update>

<Update label="2026-06-02" description="User events — isNewDevice client priority" tags={["Events", "API", "Docs"]}>
  ## `POST /events/user` — `isNewDevice` honors integrator value

  * If you send **`isNewDevice: true` or `false`**, gu1 **persists exactly that value** (no server override).
  * If you **omit** the field, gu1 infers it when **`deviceId` + `deviceDetails`** are present (device registry; `true` when the device is new or `firstSeenAt` is within the last **5 minutes**); otherwise **`false`**.

  Documented in [Create user event](/en/api-reference/events/create#how-isnewdevice-works) and [Events overview](/en/api-reference/events/overview). Parity in `/es/` and `/pt/`.
</Update>

<Update label="2026-06-01" description="Entity import — attributes / entityData dot notation" tags={["Entities", "Bulk import", "API"]}>
  ## Platform CSV: `attributes.*` and `entityData.*`

  * Dotted headers (same approach as native transaction CSV): `attributes.segment_tag`, `entityData.income`, `entityData.tradeName`.
  * **`entityData.<field>`** without `person`/`company` uses the row **`type`** bucket.
  * Unprefixed columns (`segment_tag`) still map to `attributes` (backward compatible).
  * See [Import entities (CSV)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-06-01" description="Bulk imports — limits and manual vs automatic" tags={["Bulk import", "API", "Docs"]}>
  ## Import limits documented (en / es / pt)

  * [Bulk imports overview](/en/api-reference/bulk-imports/overview): matrix of **max files per request**, **max rows by plan**, and **manual vs automatic** entity import.
  * Per-endpoint pages now include limits: [Import entities (CSV)](/en/api-reference/bulk-imports/import-entities), [Import transactions](/en/api-reference/bulk-imports/import-transactions), [Import user events](/en/api-reference/bulk-imports/import-user-events).
  * CSV entity import uses **plan limits** (4k–100k). Runtime caps: `GET /individual-organization/batch-upload-enabled`.

  Parity in `/es/` and `/pt/` docs.
</Update>

<Update label="2026-06-01" description="Entity import — countries by mode" tags={["Entities", "Bulk import", "API"]}>
  ## Bulk entity import countries (manual vs automatic)

  * **Manual** (`manual`): any **valid platform ISO2** (batch or per-row `country` / `country_code`).
  * **Automatic** (`automatic`): **AR**, **BR**, and **CL** (basic data by tax ID, including Chile ruts.info / BaseAPI enrichments).
  * Applies to **`POST /batch-import/import/entities`** (platform CSV and custom CSV with `mappingId`).

  See [Import entities (CSV)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-06-01" description="Entity import — manual multipart alignments" tags={["Entities", "Bulk import", "API"]}>
  ## `POST /batch-import/import/entities` — manual mode enrichments

  * **Manual** multipart now matches the dashboard **Manual** hub mode: optional **`autoExecuteIntegrations`**, **`monitoring`**, and risk matrices — **without** the country basic-data pipeline (Nosis/CPF).
  * CSV-only upload (no `autoExecuteIntegrations`) still creates **minimal** entities with **no** enrichments.
  * Per-row CSV enrichment columns apply in manual mode; **`depth`** / shareholders remain **automatic-only**.

  See [Import entities (CSV)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-06-01" description="Entity import — API default manual" tags={["Entities", "Bulk import", "API"]}>
  ## `POST /batch-import/import/entities` — manual default

  * Omitting **`entityImportMode`** → **`manual`** (minimal entity; enrichments only when explicitly requested).
  * **Automatic** with **`entityImportMode=automatic`** (+ optional `autoExecuteIntegrations`, `depth`, etc.).
  * Manual mode requires **`suggested_name`** on every row (`400` if missing).
  * Template **`bulk-entities-template.csv`**: documented columns; demo row without active enrichments.
  * **`202`** response includes effective **`importMode`**.

  See [Import entities (CSV)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-06-01" description="Entity import — platform CSV without mappingId" tags={["Entities", "Bulk import", "API"]}>
  ## `POST /batch-import/import/entities` — platform format

  * **`mappingId` optional** for platform CSV headers. Import default: **`manual`** (see next changelog entry on this date).

  See [Import entities (CSV)](/en/api-reference/bulk-imports/import-entities).
</Update>

<Update label="2026-06-01" description="Async transaction rules evaluation" tags={["Transactions", "Rules", "API"]}>
  ## `asyncRules` on create transaction

  * **`POST /transactions`**: optional query or body flag **`asyncRules`** (default **`false`**). When `true` and `executeRules` is not `false`, the transaction is created in the same request but rules run **in the background** via a job queue. The HTTP response returns immediately with empty `rulesHit` / `rulesNoHit`, plus **`asyncRules: true`** and **`rulesEvaluationStatus: "queued"`**.
  * **Default unchanged:** omitting `asyncRules` keeps **synchronous** rules execution and a full `rulesExecutionSummary` — existing clients behave exactly as before.
  * **Legacy KYT** `POST /legacy/kyt/verifyTransaction`: same flag via query or Gu2 body field. **Paytime prod** (`3bc1f621-27d4-423e-9d64-86680bec2388`) defaults to async when the flag is omitted; use `asyncRules=false` to force synchronous rules for a single request.
  * **Not on batch endpoints.** If Redis/queue is unavailable, API may return **503** `ASYNC_RULES_QUEUE_UNAVAILABLE` (transaction may already exist — check response body before retry).

  See [Create transaction](/en/api-reference/transactions/create).
</Update>

<Update label="2026-05-29" description="Face Match & ID Verification — RENAPER double-check" tags={["KYC", "API"]}>
  ## RENAPER double-check on standalone KYC endpoints

  * **`POST /api/kyc/face-match`**: optional `doubleCheckRenaper` (body or `?doubleCheckRenaper=true`). After Gu1 face match approves, runs RENAPER **biometric** (`validate-dni` with selfie) and **data** (DNI + trámite). Requires `documentNumber`, `gender`, and `personalNumber` (or entity fallback for DNI/gender). Response adds `responseDoubleChecks.renaper` (including nested `renaperBiometric` when biometric check runs).
  * **`POST /api/kyc/id-verification`**: same flag; after OCR approval runs RENAPER **data** check only (fields from `extractedData`). Failed checks set `status` to `declined` and add RENAPER codes to `warnings`.
  * Org **RENAPER credentials** required (same as session KYC). Use HTTP timeout ≥ 60s for face-match with double-check.

  See [Face Match](/en/use-cases/kyc/face-match) and [ID Verification](/en/use-cases/kyc/id-verification).
</Update>

<Update label="2026-05-29" description="Transaction status-change rule trigger" tags={["Transactions", "Rules", "API"]}>
  ## KYT — separate status-change vs field-update triggers

  * **`PATCH …/changeStatus`** now runs rules/matrices with trigger **`status_changed`** (`trigger_transaction_status_changed`), not `updated`.
  * **`PATCH /transactions/{id}`** (metadata, **deviceDetails**, channel, reason) with `executeRules=true` still uses **`updated`** (`trigger_transaction_updated`).
  * **Migration:** reconfigure rules that must run on status transitions to the new trigger (Rule Builder: *On transaction status change*; matrices: `transaction_status_changed`). Rules with only `updated` / *Transaction updated* no longer run on changeStatus.

  See [Change status](/en/use-cases/transaction-monitoring/change-status-api) and [Update transaction](/en/api-reference/transactions/update).
</Update>

<Update label="2026-05-29" description="PATCH transaction — metadata, deviceDetails, channel, reason" tags={["Transactions", "API"]}>
  ## Partial transaction update

  * **`PATCH /transactions/{id}`** and **`PATCH /transactions/external/{externalId}`**: update **`metadata`** (shallow merge — omitted keys are preserved), **`deviceDetails`** (shallow merge into `device_details`), **`channel`** (nullable), and/or **`reason`** (enum). Requires `transactions:edit`.
  * Query **`executeRules=true`** optionally re-runs KYT rules with trigger **`updated`** (`trigger_transaction_updated`) — not status-change rules.
  * Emits audit `transaction_updated` and webhook `transaction.updated` with a `changes` map (includes `deviceDetails` when patched).

  See [Update transaction](/en/api-reference/transactions/update).
</Update>

<Update label="2026-05-29" description="Has events by entity — query identifiers" tags={["Events", "API"]}>
  ## User events — has-events by external ID or tax ID

  * **`GET /events/user/entity/has-events`** (new): boolean check without the internal entity UUID. Query params: `entity_id`, `entity_external_id`, or `tax_id` (at least one required). Lookup priority: `entity_id` → `entity_external_id` → `tax_id`; tax IDs are matched with normalization (non-alphanumeric stripped).
  * Response still includes resolved **`entityId`** so you can call [List by Entity](/en/api-reference/events/list-by-entity) when `hasEvents` is true.
  * **`GET /events/user/entity/{entityId}/has-events`** remains supported (unchanged contract).

  See [Has events by entity](/en/api-reference/events/has-events-by-entity).
</Update>

<Update label="2026-05-28" description="KYC IP analysis warning codes" tags={["KYC", "API"]}>
  ## Session KYC — Device & IP analysis warnings

  * **`GET /api/kyc/validations/:id`** (and sync/webhook paths): the top-level **`warnings`** array now merges **`risk`** codes from **`decision.ip_analyses[].warnings[]`** (and legacy `decision.ip_analysis.warnings`), alongside ID verification, liveness, face match, and AML.
  * Eight provider codes are supported (e.g. `PRIVATE_NETWORK_DETECTED`, `DUPLICATED_DEVICE_FINGERPRINT`, `IP_ADDRESS_IN_BLOCKLIST`). See [KYC Warning Risk Codes — Device & IP Analysis](/en/use-cases/kyc/warning-risk-codes#device--ip-analysis-session-based-kyc).
  * The same codes are valid in **`omitWarnings`** on [`POST /api/kyc/validations`](/en/use-cases/kyc/create-validation) when auto-approving `in_review` sessions.

  **Integrator note:** Existing validations keep their stored `warnings` until the next sync; re-fetch or sync to backfill IP analysis codes on older rows.
</Update>

<Update label="2026-05-26" description="ID Verification extractedData expansion" tags={["KYC", "API"]}>
  ## ID Verification — richer `extractedData`

  * **`POST /api/kyc/id-verification`** and audit list/get now persist and return a broader `extractedData` object: identity fields (`personalNumber`, `taxNumber`, `placeOfBirth`, …), `providerStatus`, `warningMeta` (e.g. duplicate session IDs), quality scores, `extraFields`, `mrz`, `parsedAddress`, `barcodes` when returned by the Gu1 ID Verification service.
  * **`warnings`** remains a string array of risk codes for i18n; use `warningMeta` inside `extractedData` for structured duplicate-session metadata.
  * External document image URLs and base64 are **not** returned; images you uploaded are available via [ID Verification images](/en/use-cases/kyc/id-verification-images).
  * **`debugProviderResponse`** may appear only in non-production Gu1 API environments (sanitized verification payload, no images).

  See [ID Verification](/en/use-cases/kyc/id-verification#extracteddata-fields).
</Update>

<Update label="2026-05-26" description="Entity operationalHours + KYT operational hours rules" tags={["Entities", "Transactions", "Rules", "API"]}>
  ## operational hours per entity (global)

  * **Entities:** Optional root field `operationalHours` (`timezone` enum + `weekly` slots). Stored in `entities.operational_hours`. Documented on [Create entity](/en/api-reference/entities/create) and related entity endpoints.
  * **Transactions:** `transaction_time_zone` enum extended (Brazil zones). Optional `timeZone` is independent of entity `operationalHours`. **`transactedAt`:** stored as UTC; ISO with `Z` unchanged for existing clients; optional local datetime + `timeZone` converts to UTC when both are sent.
  * **Rules:** New operators `outside_entity_operational_hours` and `inside_entity_operational_hours` on `transactedAt` with value `origin` or `destination`. Requires `operationalHours` on the linked entity.

  See [Create transaction](/en/api-reference/transactions/create) and transactional rules knowledge base.
</Update>

<Update label="2026-05-22" description="Optional timeZone on transactions" tags={["Transactions", "API", "Database"]}>
  ## `timeZone` on transactions

  * **Database:** New nullable column `time_zone` on `transactions` with enum type `transaction_time_zone` (IANA values such as `America/Argentina/Buenos_Aires`, `UTC`, etc.). Existing rows remain `null`.
  * **API:** Optional `timeZone` on `POST /transactions` and batch create; returned on `GET /transactions/{id}` and `GET /transactions/external/{externalId}` as `string | null`.

  See [Transaction Time Zone Enum](/en/api-reference/transactions/time-zone-enum) and [Create transaction](/en/api-reference/transactions/create).
</Update>

<Update label="2026-05-21" description="validateExistingEntity on transactions" tags={["Transactions", "API", "Legacy"]}>
  ## `validateExistingEntity` (transaction create)

  * **`POST /transactions`**: optional `validateExistingEntity` (default **`false`**). When `true`, every origin/destination identifier you send must resolve to an existing person/company; otherwise **400** `INVALID_ENTITY_REFERENCES` and no row is created.
  * **Batch** endpoints: default remains **`true`**. Use `validateExistingEntity: false` for permissive bulk import.
  * **Legacy KYT** `POST /legacy/kyt/verifyTransaction`: same field in the Gu2 body.

  See [Create transaction](/en/api-reference/transactions/create) and [Batch create](/en/api-reference/transactions/create-batch).
</Update>

<Update label="2026-05-21" description="Entity creation auto-execute" tags={["Entities", "API", "Enrichment"]}>
  ## `excludeEnrichments` on entity creation

  `autoExecuteIntegrations` and `autoExecuteIntegrationsShareholders` (manual `POST /entities`, `POST /entities/automatic`, bulk import, materialize) now accept **`excludeEnrichments`**: an array of provider codes removed from the final enrichment set after merge (including when `executeAllActiveEnrichments` is `true`).

  **`executeAllActiveChecks` and `checks` are no longer part of the public contract** for these objects. Legacy payloads that still send them are ignored at parse time.

  See [Create entity (automatic)](/en/api-reference/entities/create-automatic) and [Create entity](/en/api-reference/entities/create).
</Update>

<Update label="2025-01-27" description="v1.3.0 - Hosted Onboarding Page Documentation" tags={["KYC", "Hosted Page", "Documentation"]}>
  ## New: Hosted Onboarding Page Documentation

  Complete documentation for the Hosted Onboarding Page - the quickest way to implement KYC verification without code.

  ### What's New

  **Hosted Page Documentation:**

  * ✅ Complete customization parameters guide (branding, colors, layout)
  * ✅ Validation rules configuration (age verification, capture methods, duplicate detection)
  * ✅ Document validation rules (QR/barcode, MRZ, expiration dates, liveness)
  * ✅ Step-by-step integration guide with code examples
  * ✅ Visual flow diagram showing the complete process
  * ✅ Security best practices for session management
  * ✅ Mobile-responsive design confirmation

  **Key Features:**

  * 📱 Mobile-responsive design for all devices
  * 🎨 Full customization of colors, branding, and layout
  * 🔒 Comprehensive security guidelines
  * 📊 Visual sequence diagrams for clarity
  * 🌐 Support channel information for configuration changes

  ### Languages

  All documentation available in:

  * 🇺🇸 English
  * 🇪🇸 Español
  * 🇧🇷 Português

  ### Impact

  * Faster implementation for no-code solutions
  * Clear guidance on customization options
  * Enhanced security awareness
  * Better understanding of the hosted page workflow

  [View Hosted Page Documentation](/en/use-cases/kyc/hosted-page)
</Update>

<Update label="2025-01-09" description="v1.2.0 - KYC Documentation Enhancement" tags={["KYC", "Documentation", "Multi-language"]}>
  ## KYC Pages Refinement Based on Client Feedback

  Major enhancement to KYC documentation based on 14 questions from client feedback.

  ### What's New

  **Complete Flow Documentation:**

  * ✅ Added comprehensive comparison table: Automatic vs Manual creation
  * ✅ Complete Risk Matrix configuration guide with dashboard instructions
  * ✅ Clarified shareholders feature (KYB only, not KYC)
  * ✅ Provider codes reference with usage examples
  * ✅ Detailed credit management section with costs and workflows

  **Overview Page:**

  * ✅ Webhooks vs manual polling explanation
  * ✅ Full KYC vs Individual Verifications comparison table
  * ✅ Comprehensive face matching security warning for banks/fintech
  * ✅ Enhanced API endpoints table with use cases

  **Create Validation Page:**

  * ✅ Complete sequence diagram showing full flow
  * ✅ Sandbox vs Production clarification
  * ✅ Duplicate entity handling with code examples
  * ✅ Expanded integrationCode documentation

  **Entities API:**

  * ✅ Marked optional fields with examples (attributes, entityData)
  * ✅ Minimal vs full entity creation examples

  ### Languages

  All improvements available in:

  * 🇺🇸 English
  * 🇪🇸 Español
  * 🇧🇷 Português

  ### Impact

  * 14 client questions answered inline
  * 12 documentation files updated
  * 0 broken links
  * Improved developer onboarding experience

  [View KYC Documentation](/en/use-cases/kyc/overview)
</Update>

<Update label="2025-01-08" description="v1.1.0 - Multi-language Support" tags={["Infrastructure", "i18n"]}>
  ## Enhanced Multi-language Documentation

  Improved documentation structure with complete Spanish and Portuguese translations.

  ### Changes

  * Complete translation coverage for KYC, KYB, and Transaction Monitoring
  * Consistent terminology across all languages
  * Language-specific examples (CPF for Brazil, DNI for Spain, etc.)

  ### Available Languages

  * English (EN) - Primary
  * Spanish (ES) - Complete
  * Portuguese (PT) - Complete
</Update>

<Update label="2024-12-20" description="v1.0.0 - Initial Release" tags={["Launch"]}>
  ## gu1 Documentation Launch

  Initial release of comprehensive API documentation.

  ### Core Features

  * Complete API reference for all endpoints
  * Use case guides (KYC, KYB, Transaction Monitoring)
  * Webhook integration guides
  * Interactive tutorials
  * Multi-language support

  ### Components

  * Person entities API
  * Company entities API
  * KYC validation workflows
  * Transaction monitoring
  * Rules engine
  * Risk matrices
  * Alerts and investigations

  [Get Started](/en/quickstart)
</Update>
