---
title: "Start a bulk import"
method: POST
path: "/v1/imports"
tags: ["Import"]
---

# Start a bulk import

`POST /v1/imports`

## Request

- Base URL: `https://api.prod.keyban.io`
- URL: `https://api.prod.keyban.io/v1/imports`
- Auth: `X-Api-Key` (a scheme the document does not define)

Upload a JSON array of entities to import in bulk for the given application.

The body schema depends on the `entityName` query parameter. Currently only `DppPassport` is supported, whose items follow `CreateDppPassportDto`.

The passport granularity is carried by `product.idGranularity`:
- `model` — product model level (shared template across a whole reference).
- `batch` — production batch level (series, dated run); set `product.modelNumber` to link to the parent model.
- `item` — individual serialized article level; set `product.batchNumber` / `product.itemNumber` to link and identify the unit.

When the optional `mapperId` query parameter is set, the body is instead a JSON array of **foreign-schema** source objects: each item is transformed into a passport via the mapper rules (replace semantics) before validation, so it need not match `CreateDppPassportDto` directly.

The optional `network` query parameter sets the blockchain network for every imported passport (it is not part of the body / mapper output). When omitted it defaults to `BaseMainnet`.

## Request body

- CreateImportJobDto
  - `applicationId` string, uuid, required: UUID of the application the import targets. Every imported entity is created under this application.
  - `entityName` 'DppPassport', required: Class name of the entity to import. Currently only `DppPassport` is supported.
  - `url` string, uri, required
  - `mapperId` string, uuid: Optional UUID of a `DppPassport` mapper (must belong to the same application). When set, each uploaded item is treated as a foreign-schema source object and transformed into a passport via the mapper rules before validation — the original fields are replaced by the mapper output. Omit to import items already shaped as `CreateDppPassportDto`.
  - `network` 'EthereumAnvil' | 'BaseSepolia' | 'BaseMainnet' | 'XdcApothem' | 'XdcMainnet' | 'StellarQuickstart' | 'StellarTestnet' | 'StellarMainnet': Blockchain network applied to every imported passport (the import body / mapper output does not carry it). Defaults to `BaseMainnet` when omitted. An explicit `network` already present on an item takes precedence.
  - `csvHasHeader` boolean: CSV imports only: whether the first row is a header to skip (`true`) or already data to import (`false`). Ignored for JSON. Column indices in the mapper are unaffected — they are always counted from the first column.

## Other responses

- `400`: Invalid import request: a CSV body without a `mapperId` (a CSV import requires a mapper), a mapper whose rows do not match the detected body format (a JSON-oriented mapper used against a CSV body, or vice versa), a missing request body (no CSV stream / no buffered JSON body), a streamed CSV body exceeding the 256 MB upload cap, or — **CSV only** — a synchronous enqueue exceeding the temporary 1,000-row cap. A JSON body exceeding the same cap does not produce this 400: the violation happens in the background enqueue and only surfaces afterwards, on the job's `initError` field or over the progress SSE.

---

[API](https://skmtc.dev/keyban/apis/keyban-rest-apis.md) · [All operations](https://skmtc.dev/keyban/apis/keyban-rest-apis/llms.txt) · [OpenAPI document](https://skmtc.dev/keyban/apis/keyban-rest-apis/revisions/0bb79a1da961?raw)
