---
title: "Get a CSV import job's status and result"
method: GET
path: "/accountant/companies/{customerId}/transactions/import-jobs/{jobId}"
tags: ["Accountant Portal", "Transactions"]
---

# Get a CSV import job's status and result

`GET /accountant/companies/{customerId}/transactions/import-jobs/{jobId}`

## Request

- Base URL: `https://api.medianfi.com/api/v1`
- URL: `https://api.medianfi.com/api/v1/accountant/companies/{customerId}/transactions/import-jobs/{jobId}`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Polling endpoint for jobs created by the CSV import endpoint. While `status` is `pending` or `running`, the counter fields report progress. Once `completed`, `summary` carries the final import summary; when `failed`, `errorMessage` explains why.

## Response `200`

Import job found

- TransactionImportJobResponse
  - `success` boolean
  - `data` TransactionImportJob: Async CSV import job as returned by the accountant portal. Counter fields report live progress while `status` is `pending` or `running`.
    - `id` string, uuid
    - `companyId` string, uuid
    - `accountId` string, uuid: The raw polymorphic `accountId` from the request; see `summary.resolvedAccount` for what it resolved to
    - `status` 'pending' | 'running' | 'completed' | 'failed'
    - `requested` integer
    - `processed` integer: Rows examined so far
    - `imported` integer
    - `skipped` integer
    - `duplicates` integer
    - `invalid` integer
    - `errors` integer
    - `sourceMapped` integer
    - `csvFingerprint` string, nullable
    - `requestId` string, nullable
    - `summary` TransactionImportSummary: Final result of one CSV import run (`ImportSummary` in the API source)
      - `requested` integer: Number of rows in the request
      - `imported` integer
      - `skipped` integer: duplicates + invalid
      - `duplicates` integer
      - `sourceMapped` integer: Imported rows linked to an integration or bank account. A Chart-of-Accounts pick counts when the importer adopted the sole bank account bound to that GL (#2119); it is 0 only when no bank account could be resolved for the deposit-to account.
      - `errors` integer: Mirrors `invalid`
      - `invalid` integer
      - `results` TransactionImportResultItem[]
        - `index` integer: 0-based position of the row in the request `rows` array
        - `rowNumber` integer: Echo of the request row's `rowNumber` when supplied
        - `status` 'imported' | 'duplicate' | 'invalid'
        - `transactionId` string, uuid: Created transaction id, or the existing transaction for duplicates
        - `externalId` string: Stable dedup identity stored in `transactions.external_id`
        - `reason` string: Why the row was skipped (`duplicate`) or rejected (`invalid`)
        - `code` string: Error code behind an `invalid` row whose write failed (for example `CONFLICT`), when the failure carried one
        - `postingError` object: Set on an `imported` row whose transaction was written but whose categorize update or journal posting then failed (#2930). The transaction is kept without a journal entry; `message` is the real failure.
          - `message` string, required
          - `code` string: Error code of the failure, when it carried one
      - `categorizationTriggered` boolean
      - `engineSubmissionTriggered` boolean
      - `bookkeepingEngineTriggered` boolean
      - `bookkeepingEngineRunId` string
      - `balancesRecomputed` boolean
      - `resolvedAccount` TransactionImportResolvedAccount: Which resolution path the polymorphic request `accountId` took and which account FKs the imported rows carry. `via: gl_account` (direct Chart-of-Accounts selection) leaves `integrationAccountId` null; `bankAccountId` is the sole non-personal bank account bound to that GL account when exactly one exists (the importer adopts it so rows stay reconcilable, #2119) and null when none or several are bound — the null case is a genuinely GL-only account with no linked bank feed, expected rather than orphaned data. Added by issue #1231; absent on summaries recorded before it shipped.
        - `via` 'integration_account' | 'bank_account' | 'gl_account': Which lookup matched the request `accountId` (table names)
        - `glAccountId` string, uuid
        - `integrationAccountId` string, uuid, nullable
        - `bankAccountId` string, uuid, nullable
        - `label` string
      - `postingFailed` integer: Imported rows carrying `postingError` (#2930). Absent on summaries recorded before it shipped.
    - `errorMessage` string, nullable: Failure detail when `status` is `failed`
    - `startedAt` string, date-time, nullable
    - `completedAt` string, date-time, nullable
    - `createdAt` string, date-time
    - `updatedAt` string, date-time

## Other responses

- `401`: Authentication required
- `403`: Insufficient permissions or not a company member
- `404`: Resource not found
- `422`: CSV import jobs are not configured on this server

---

[API](https://skmtc.dev/medianfi/apis/median-api.md) · [All operations](https://skmtc.dev/medianfi/apis/median-api/llms.txt) · [OpenAPI document](https://skmtc.dev/medianfi/apis/median-api/revisions/20090ea32b0d?raw)
