> ## 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.

# Batch import failure codes

> Stable error codes for row-level and job-level failures in batch imports of transactions, entities, and user events, with retry guidance.

## Failure Download Endpoints

| Resource     | CSV                                                       | JSON                                                                            |
| ------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Transactions | `GET /batch-import/transaction-jobs/{jobId}/failures.csv` | [GET …/failures](/en/api-reference/bulk-imports/get-transaction-batch-failures) |
| User events  | `GET /batch-import/user-event-jobs/{jobId}/failures.csv`  | [GET …/failures](/en/api-reference/bulk-imports/get-user-event-batch-failures)  |
| Entities     | `GET /batch-import/entity-jobs/{jobId}/failures.csv`      | [GET …/failures](/en/api-reference/bulk-imports/get-entity-batch-failures)      |

Legacy entity CSV alias: `GET /entities/automatic/bulk/imports/{jobId}/failures.csv`.

* **`…/failures.csv`** → CSV file download (`Content-Type: text/csv`)
* **`…/failures`** → JSON body (`Content-Type: application/json`)

## Overview

Batch imports expose failures at **three layers**:

| Layer         | When                                                          | Where to read                                                                                                                             |
| ------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Pre-job**   | Request rejected before `jobId` is returned (`400`)           | HTTP response body (`error.code`)                                                                                                         |
| **Job-level** | Whole job aborted (`status: failed`)                          | [Unified history](/en/api-reference/bulk-imports/list-unified-history) → `workerError`, `metadata.apiError`; JSON failures → `jobFailure` |
| **Row-level** | Some rows failed (`failed > 0`, job may still be `completed`) | [Failures CSV/JSON](/en/api-reference/bulk-imports/get-transaction-batch-failures) per kind                                               |

Row-level failures always include a stable **`code`** (machine-readable) and **`message`** (human detail). Legacy jobs may only have free-text `error`; the API normalizes them on read.

## Entity Row Outcomes (Created / Skipped / Failed)

| Outcome            | In `failures.csv`?     | Where                                                              |
| ------------------ | ---------------------- | ------------------------------------------------------------------ |
| `created`          | No                     | Job `succeeded`                                                    |
| `skipped_existing` | **No** — not a failure | Job `skipped` / `skippedExisting`, full report CSV, JSON `skips[]` |
| `failed`           | **Yes**                | `failures.csv`, JSON `failures[]`                                  |

### Duplicate `taxId` (Entities)

**Bulk manual default** uses `duplicateTaxIdPolicy: skip_existing`:

* Same `taxId` + same `type` already in org → **`skipped_existing`**, skip code **`SKIPPED_DUPLICATE_TAX_ID`**
* Does **not** appear in `failures.csv`

**Bulk automatic:** existing main entity → **`skipped_existing`**

* **`refresh: false`** (default when omitted): **`SKIPPED_ENTITY_ALREADY_EXISTS`** — no re-enrichment
* **`refresh: true`**: **`SKIPPED_ENTITY_ALREADY_EXISTS_REFRESHED`** — creation skipped, re-enrichment ran

**Hard failures:**

| Situation                                                        | Failure code            |
| ---------------------------------------------------------------- | ----------------------- |
| Same taxId, **different** type (person vs company)               | `TAX_ID_TYPE_MISMATCH`  |
| Same taxId + type with error policy (unit API; not bulk default) | `DUPLICATE_TAX_ID`      |
| Duplicate `externalId`                                           | `DUPLICATE_EXTERNAL_ID` |

## Row-level failure codes (`BATCH_IMPORT_ITEM_FAILURE_CODES`)

| Code                               | Meaning                                                                                  |
| ---------------------------------- | ---------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`                 | Row failed Zod / schema validation before persistence.                                   |
| `PROCESSING_ERROR`                 | Unexpected error while processing the row.                                               |
| `ENTITY_NOT_FOUND`                 | Referenced entity does not exist in the organization.                                    |
| `INVALID_RISK_MATRIX`              | Risk matrix id invalid or not in org.                                                    |
| `CREATION_CONTRACT_QUOTA_EXCEEDED` | Organization contract creation quota exceeded.                                           |
| `CREATION_QUOTA_EXCEEDED`          | Deprecated alias of `CREATION_CONTRACT_QUOTA_EXCEEDED` (historical `failures.csv` only). |
| `DATABASE_INSERT_ERROR`            | Database rejected insert (unclassified).                                                 |
| `DUPLICATE_EXTERNAL_ID`            | Entity or transaction with same `externalId` already exists.                             |
| `DUPLICATE_TAX_ID`                 | Same taxId + type already exists (hard error path).                                      |
| `TAX_ID_TYPE_MISMATCH`             | taxId registered under a different entity type.                                          |
| `CONSTRAINT_VIOLATION`             | Other DB constraint (FK, check, unique index).                                           |
| `MISSING_COUNTRY`                  | Entity row missing valid ISO2 country.                                                   |
| `INVALID_COUNTRY`                  | Country not allowed for import mode (e.g. automatic ≠ AR/BR/CL).                         |
| `ENRICHMENT_FAILED`                | Enrichment provider failed for entity row.                                               |
| `CREATION_FAILED`                  | Entity could not be created for the row.                                                 |

## Skip reason codes (`BATCH_IMPORT_SKIP_REASON_CODES`)

Not failures — used when `outcome=skipped_existing`:

| Code                                      | Meaning                                                                |
| ----------------------------------------- | ---------------------------------------------------------------------- |
| `SKIPPED_DUPLICATE_TAX_ID`                | Manual bulk skipped row: duplicate taxId + type                        |
| `SKIPPED_ENTITY_ALREADY_EXISTS`           | Automatic bulk: entity already existed, refresh off                    |
| `SKIPPED_ENTITY_ALREADY_EXISTS_REFRESHED` | Automatic bulk: entity already existed, refresh on — re-enrichment ran |

<Note>
  **Risk matrix / business rules:** rule execution runs **after** the row is created. Rule outcomes do **not** appear in `failures.csv` / JSON `failures[]` and do not roll back the row. Use alerts, risk score, and audit timelines for rule results.
</Note>

## Job-level codes (`BATCH_IMPORT_JOB_FAILURE_CODES`)

| Code                        | Meaning                                                                                                        |
| --------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `INVALID_ENTITY_REFERENCES` | Transaction batch: `validateExistingEntity=true` and unresolved origin/destination refs — **no rows created**. |
| `TOO_MANY_ITEMS`            | File exceeds plan row limit.                                                                                   |
| `CSV_PARSE_ERROR`           | CSV could not be parsed or mapped.                                                                             |
| `MAPPING_VALIDATION_ERROR`  | Saved mapping or validate-csv preflight failed.                                                                |
| `MISSING_REQUIRED_FIELD`    | Required multipart / row field missing before queue.                                                           |
| `COOPERATIVE_CANCEL`        | Job cancelled while processing.                                                                                |
| `WORKER_ERROR`              | Unhandled worker error.                                                                                        |

## Scenario Matrix (Client FAQ)

| Scenario                                              | In row `failures`? | Typical code / location                                      |
| ----------------------------------------------------- | ------------------ | ------------------------------------------------------------ |
| Missing CSV column (pre-parse)                        | No                 | `400` before job                                             |
| Invalid entity ref (txn batch, default validation)    | No                 | Job `INVALID_ENTITY_REFERENCES`                              |
| Duplicate txn `externalId` with `skipDuplicates=true` | No                 | Counted as `skipped`                                         |
| Duplicate entity `externalId` (manual import)         | Yes                | `DUPLICATE_EXTERNAL_ID`                                      |
| Duplicate entity `taxId` (same type, bulk default)    | No                 | `skipped_existing` → `SKIPPED_DUPLICATE_TAX_ID` in `skips[]` |
| Duplicate entity `taxId` (type mismatch)              | Yes                | `TAX_ID_TYPE_MISMATCH`                                       |
| Enrichment failure (entity automatic)                 | Yes                | `ENRICHMENT_FAILED`                                          |
| User event invalid field                              | Yes                | `VALIDATION_ERROR`                                           |
| Rules / matrix evaluation error                       | No                 | Row still created                                            |

## Reproducible Test Scenarios

**User events (simplest row failures):** valid CSV + mapping; one row with empty required field → `GET …/user-event-jobs/{jobId}/failures`.

**Entities (manual):** create entity with `external_id=X`, import another row with same `external_id` → `DUPLICATE_EXTERNAL_ID`.

**Transactions (job-level):** `validateExistingEntity=true` + `originExternalId=DOES_NOT_EXIST` → job `failed`, `jobFailure.code=INVALID_ENTITY_REFERENCES`.

**Transactions (row-level):** `batchErrorHandling=continue_collect_errors` + mix valid rows with DB constraint violations → row entries in failures endpoint.

## Limits

* Max **500** row failures persisted per transaction batch job (CSV + JSON may truncate; JSON exposes `truncated` + `failuresTotal`).

See also: [Bulk imports overview](/en/api-reference/bulk-imports/overview).
