---
title: "Get the latest import job of a schema"
method: GET
path: "/v1/entity:import:latest"
tags: ["Import-Export"]
---

# Get the latest import job of a schema

`GET /v1/entity:import:latest`

## Request

- Base URL: `https://entity.sls.epilot.io`
- URL: `https://entity.sls.epilot.io/v1/entity:import:latest`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-epilot-org-id`

Returns the progress of the latest import job for the organization and schema: the running job,
whoever started it (it blocks every other import of the schema), otherwise the caller's own last
finished job if it finished within the last 24 hours. Used to show the state of an import (or dry
run) that was started earlier.

## Query parameters

- `schema` string, required

## Response `200`

Progress of the latest import job.

- ImportProgress: Progress of an import job. The fields `dry_run`, `unique_key`, `outcome_counts`, `report_url`, `S3Reference` and `started_by` are only set for jobs started with `unique_key`, `dry_run` or `dry_run_job_id`. For those, `importedEntitiesCount` is `create` plus `update` and `failedEntitiesCount` counts `error` rows only.
  - `jobPollId` string: The ID of the import job.
  - `trigger_automations` boolean: Whether committed rows of the job trigger automations.
  - `started_by` string: User id of whoever started the job. A finished job is only returned by `entity:import:latest` to this user, and only this user can commit or discard a dry run.
  - `status` 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'CANCELLED'
  - `total` integer: Number of data rows in the file, once known.
  - `importedEntitiesCount` integer
  - `failedEntitiesCount` integer
  - `importedEntitiesUrl` string
  - `failedEntitiesUrl` string
  - `updated_at` string, date-time
  - `failure_reason` string
  - `failure_code` 'invalid_csv_bad_headers' | 'dry_run_required' | 'dry_run_mismatch' | 'dry_run_expired' | 'import_file_changed' | 'prescan_missing' | 'import_too_large' | 'token_expired' | 'max_duration_exceeded' | 'no_progress' | 'internal_error': Machine readable reason of a failed job. `failure_reason` holds the human text. - `invalid_csv_bad_headers`: the file has neither a `_schema` nor an `_id` column - `dry_run_required`, `dry_run_mismatch`, `dry_run_expired`: the dry-run rule rejected the commit before any row - `import_file_changed`: the file was replaced after the pre-scan - `prescan_missing`: the job cannot be continued after an update - `import_too_large`: the file has more rows than a single job can report on - `token_expired`: the session that started the job expired before it finished - `max_duration_exceeded`: the job ran longer than allowed - `no_progress`: consecutive runs made no progress - `internal_error`: an unexpected error ended the job
  - `abortable` boolean
  - `dry_run` boolean
  - `unique_key` string[]
  - `outcome_counts` ImportRowOutcomeCounts: Number of rows per outcome, in the order the outcomes are evaluated.
    - `error` integer
    - `skipped_empty_key` integer
    - `skipped_duplicate_in_file` integer
    - `skipped_id_not_found` integer
    - `skipped_ambiguous` integer
    - `create` integer
    - `unchanged` integer
    - `update` integer
  - `report_url` string: Download link of the per-row report (CSV, UTF-8 with BOM).
  - `S3Reference` object: The imported file. Send it back with `dry_run_job_id` to commit a dry run.
    - `bucket` string
    - `key` string
  - `issues` ImportIssue[]: The rows that are not written, grouped by why: blocking issues first, then by count, at most 20. The warnings always get a place. Blocking issues beyond the 50 tracked are counted as `Other errors`. Only for jobs started with `unique_key`, `dry_run` or `dry_run_job_id`.
    - `severity` 'blocking' | 'warning', required: `blocking` for rows with the outcome `error`, `warning` for the `skipped_*` outcomes.
    - `reason` string, required: Blocking: the row reason's text before its first `: `, one issue per `; `-separated part, e.g. `Invalid date for birthdate` or `Unknown purpose id`. Warning: the outcome, e.g. `skipped_duplicate_in_file`.
    - `column` string: The column the reason names (`… for <column>` or `… in <column>`), if any.
    - `count` integer, required: Number of rows with this issue.
    - `example_rows` integer[], required: The first (at most 5) row numbers with this issue, 1-based data rows as in the report.
  - `phase` 'scanning' | 'dry_run' | 'importing' | 'finalizing' | 'done': What the job is doing now: `scanning` the file (pre-scan), running the `dry_run` or `importing` rows, `finalizing` the report, or `done` (every terminal status).
  - `heartbeat_at` string, date-time: Refreshed at every phase change and at least every few seconds while the job makes progress (rows or pre-scan). A PROCESSING job whose heartbeat is minutes old may be stuck.
  - `started_at` string, date-time: When the job started.
  - `finished_at` string, date-time: When the job ended; set on a terminal status.

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `404`: No import job for this schema in the last 24 hours
- `429`: Too many requests

## Changes

- **2026-10-15** `299db8038dd4`: 11 warning, 5 info
  - added the new `dry_run_expired` enum value to the `failure_code` response property for the response status `200`
  - added the new `dry_run_mismatch` enum value to the `failure_code` response property for the response status `200`
  - added the new `dry_run_required` enum value to the `failure_code` response property for the response status `200`
  - added the new `import_file_changed` enum value to the `failure_code` response property for the response status `200`
  - …12 more
- **2026-10-07** `dcab4cb50e1b`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/epilot/apis/entity-api/changes/v1/entity:import:latest/get.md)

---

[API](https://skmtc.dev/epilot/apis/entity-api.md) - [All operations](https://skmtc.dev/epilot/apis/entity-api/llms.txt) - [OpenAPI document](https://skmtc.dev/epilot/apis/entity-api/revisions/b7d4f45d1518?raw)
