# Get CRM import run

Read a CRM import’s progress and per-object counts. Created and updated counts describe records written; skipped records and limitations explain what was left out. Requires an owner or administrator. The same job ID can be used with workspace.GetJob by the person who started it.

POST https://api.brigg.app/v1/operations/customers.GetCrmImportRun

## Access & visibility

Allow `customers.GetCrmImportRun` on your API key.

**Workspace access by default.** Private member data requires [approved member delegation](https://developer.brigg.app/authentication#member-delegation) through `Brigg-Act-As`; the key supplies permissions while private ownership and project boundaries remain enforced.

[Set up authentication](https://developer.brigg.app/authentication) · [Choose permissions](https://developer.brigg.app/permissions)

## Request fields

Send a JSON object with the following fields. Required fields must be included; omit optional fields you do not need.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `job_id` | string | Yes | Run identifier. At least 1 character. |

## Import from a connected CRM

Use [Get CRM import status](https://developer.brigg.app/reference/customers/GetCrmImportStatus) to inspect the HubSpot connection, supported objects and the most recent run. [Preview CRM import](https://developer.brigg.app/reference/customers/PreviewCrmImport) reads a sample without writing contacts. A missing provider scope requires reconnecting in Brigg; an API grant cannot supply missing provider consent.

Start the connected-CRM import in Brigg. [Get CRM import run](https://developer.brigg.app/reference/customers/GetCrmImportRun) reads its progress and detailed report. Review created, updated, skipped and not-imported counts; a finished run does not mean every source object was supported.

To import through the public API, use [Start record import](https://developer.brigg.app/reference/integrations/StartRecordImport) with a file and permanent external references. That workflow keeps the credential’s approved operation and resource permissions throughout background processing.

## Response

Returns **200 OK** with a JSON body.
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `job_id` | string | Yes | Run identifier. |
| `status` | string | Yes | queued \| running \| done \| failed |
| `progress_percent` | number | Yes | Progress pct. |
| `phase` | string | No | Current phase of the background import or preparation job. |
| `report` | [CrmImportReport](#crmimportreport-response-report) | Yes | Import counts, exclusions and limitations from the run. |
| `started_at` | number | Yes | Time this work started, in Unix milliseconds. |
| `completed_at` | number or null | No | Time this work completed, in Unix milliseconds. |

### CrmImportReport · response.report

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `counts` | [object](#response-report-counts) | Yes | Per-object counts for the import. |
| `limitations` | array of [object](#response-report-limitations) | Yes | Known exclusions or incomplete coverage in this import run. |
| `portal` | [object](#response-report-portal) | No | Provider account or portal identifier used by this connection. |

### response.report.counts

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `companies` | [object](#response-report-counts-companies) | No | Company records included in the import or search. |
| `contacts` | [object](#response-report-counts-contacts) | No | Contact records included in the import. |
| `deals` | [object](#response-report-counts-deals) | No | Sales opportunity records included in the import. |
| `notes` | [object](#response-report-counts-notes) | No | Note records included in the import. |
| `tasks` | [object](#response-report-counts-tasks) | No | Task records included in the import. |

### response.report.counts.companies

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scanned` | number | Yes | Source records examined by the import. |
| `created` | number | Yes | Records newly created by the import, or whether this reusable item was newly created. |
| `updated` | number | Yes | Existing records updated by the import. |
| `skipped` | number | Yes | Source records left unchanged or not imported. |

### response.report.counts.contacts

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scanned` | number | Yes | Source records examined by the import. |
| `created` | number | Yes | Records newly created by the import, or whether this reusable item was newly created. |
| `updated` | number | Yes | Existing records updated by the import. |
| `skipped` | number | Yes | Source records left unchanged or not imported. |

### response.report.counts.deals

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scanned` | number | Yes | Source records examined by the import. |
| `created` | number | Yes | Records newly created by the import, or whether this reusable item was newly created. |
| `updated` | number | Yes | Existing records updated by the import. |
| `skipped` | number | Yes | Source records left unchanged or not imported. |

### response.report.counts.notes

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scanned` | number | Yes | Source records examined by the import. |
| `created` | number | Yes | Records newly created by the import, or whether this reusable item was newly created. |
| `updated` | number | Yes | Existing records updated by the import. |
| `skipped` | number | Yes | Source records left unchanged or not imported. |

### response.report.counts.tasks

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scanned` | number | Yes | Source records examined by the import. |
| `created` | number | Yes | Records newly created by the import, or whether this reusable item was newly created. |
| `updated` | number | Yes | Existing records updated by the import. |
| `skipped` | number | Yes | Source records left unchanged or not imported. |

### response.report.limitations[]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `key` | string | Yes | Stable key identifying this option within its collection; distinct from its display label. |
| `reason` | string | Yes | Explanation of why this outcome occurred. Allowed: `"missing_scope"`, `"no_equivalent"`, `"degraded"`, `"not_available"`. |
| `detail` | string | No | Additional explanation of the reported result. |
| `count` | number | No | Number of matching items represented by this result. |

### response.report.portal

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | No | Unique identifier. Use the value returned by a create or list operation. |
| `domain` | string | No | Website hostname, without a scheme or path. |
| `currency` | string | No | Three-letter currency code, such as NOK, SEK or EUR. |

## Errors & retries

This operation reads data. It needs no idempotency key and can be retried after a transient failure.

For rate limits, follow the server’s retry guidance and back off. See [HTTP errors](https://developer.brigg.app/http#errors) and [safe retries and limits](https://developer.brigg.app/reliability).

| HTTP status | Code | What to do |
| --- | --- | --- |
| 400 | `invalid_json` | Send a JSON object with Content-Type: application/json. |
| 400 | `invalid_input` | Check the request fields and types. |
| 401 | `invalid_key` | The workspace API key is missing, invalid or revoked. |
| 403 | `forbidden` | Check the key’s operation and resource grants. If Brigg-Act-As is supplied, the key must be authorized to delegate to that member. |
| 404 | `not_found` | The requested operation or resource is not available to this credential. |
| 429 | `rate_limited` | Wait for Retry-After before retrying. |

## Next steps

- [Get CRM import status](https://developer.brigg.app/reference/customers/GetCrmImportStatus)
- [Preview CRM import](https://developer.brigg.app/reference/customers/PreviewCrmImport)
- [Track the background job](https://developer.brigg.app/reference/workspace/GetJob)

[Download OpenAPI](https://developer.brigg.app/openapi.json) · [Versioning & retirement](https://developer.brigg.app/versioning)

## Examples

### Example request

Fictional values. Replace IDs and business details with values from your workspace.
#### cURL


```sh
curl 'https://api.brigg.app/v1/operations/customers.GetCrmImportRun' \
  -H "Authorization: Bearer $BRIGG_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "job_id": "e_example"
}'
```

#### TypeScript


```typescript
const response = await fetch("https://api.brigg.app/v1/operations/customers.GetCrmImportRun", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BRIGG_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "job_id": "e_example"
  }),
});
const result = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${result.error} — ${result.message}`);
console.log(result);
```

#### Python


```python
import json
import os
from urllib.request import Request, urlopen
from urllib.error import HTTPError

payload = {
  "job_id": "e_example"
}
request = Request(
    "https://api.brigg.app/v1/operations/customers.GetCrmImportRun",
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {os.environ['BRIGG_API_KEY']}",
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urlopen(request) as response:
        print(json.load(response))
except HTTPError as error:
    print(error.code, json.load(error))
    raise
```

#### Response example


```json
{
  "job_id": "e_example",
  "status": "completed",
  "progress_percent": 1,
  "report": {
    "counts": {},
    "limitations": []
  },
  "started_at": 1794301200000
}
```

## JSON schemas


```json-schema-request
{
  "type": "object",
  "properties": {
    "job_id": {
      "type": "string",
      "minLength": 1,
      "description": "Run identifier."
    }
  },
  "required": [
    "job_id"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "job_id": "e_example"
    }
  ]
}
```


```json-schema-response
{
  "type": "object",
  "properties": {
    "job_id": {
      "type": "string",
      "description": "Run identifier."
    },
    "status": {
      "type": "string",
      "description": "queued | running | done | failed"
    },
    "progress_percent": {
      "type": "number",
      "description": "Progress pct."
    },
    "phase": {
      "type": "string",
      "description": "Current phase of the background import or preparation job."
    },
    "report": {
      "description": "Import counts, exclusions and limitations from the run.",
      "title": "CrmImportReport",
      "type": "object",
      "properties": {
        "counts": {
          "type": "object",
          "properties": {
            "companies": {
              "type": "object",
              "properties": {
                "scanned": {
                  "type": "number",
                  "description": "Source records examined by the import."
                },
                "created": {
                  "type": "number",
                  "description": "Records newly created by the import, or whether this reusable item was newly created."
                },
                "updated": {
                  "type": "number",
                  "description": "Existing records updated by the import."
                },
                "skipped": {
                  "type": "number",
                  "description": "Source records left unchanged or not imported."
                }
              },
              "required": [
                "scanned",
                "created",
                "updated",
                "skipped"
              ],
              "additionalProperties": false,
              "description": "Company records included in the import or search."
            },
            "contacts": {
              "type": "object",
              "properties": {
                "scanned": {
                  "type": "number",
                  "description": "Source records examined by the import."
                },
                "created": {
                  "type": "number",
                  "description": "Records newly created by the import, or whether this reusable item was newly created."
                },
                "updated": {
                  "type": "number",
                  "description": "Existing records updated by the import."
                },
                "skipped": {
                  "type": "number",
                  "description": "Source records left unchanged or not imported."
                }
              },
              "required": [
                "scanned",
                "created",
                "updated",
                "skipped"
              ],
              "additionalProperties": false,
              "description": "Contact records included in the import."
            },
            "deals": {
              "type": "object",
              "properties": {
                "scanned": {
                  "type": "number",
                  "description": "Source records examined by the import."
                },
                "created": {
                  "type": "number",
                  "description": "Records newly created by the import, or whether this reusable item was newly created."
                },
                "updated": {
                  "type": "number",
                  "description": "Existing records updated by the import."
                },
                "skipped": {
                  "type": "number",
                  "description": "Source records left unchanged or not imported."
                }
              },
              "required": [
                "scanned",
                "created",
                "updated",
                "skipped"
              ],
              "additionalProperties": false,
              "description": "Sales opportunity records included in the import."
            },
            "notes": {
              "type": "object",
              "properties": {
                "scanned": {
                  "type": "number",
                  "description": "Source records examined by the import."
                },
                "created": {
                  "type": "number",
                  "description": "Records newly created by the import, or whether this reusable item was newly created."
                },
                "updated": {
                  "type": "number",
                  "description": "Existing records updated by the import."
                },
                "skipped": {
                  "type": "number",
                  "description": "Source records left unchanged or not imported."
                }
              },
              "required": [
                "scanned",
                "created",
                "updated",
                "skipped"
              ],
              "additionalProperties": false,
              "description": "Note records included in the import."
            },
            "tasks": {
              "type": "object",
              "properties": {
                "scanned": {
                  "type": "number",
                  "description": "Source records examined by the import."
                },
                "created": {
                  "type": "number",
                  "description": "Records newly created by the import, or whether this reusable item was newly created."
                },
                "updated": {
                  "type": "number",
                  "description": "Existing records updated by the import."
                },
                "skipped": {
                  "type": "number",
                  "description": "Source records left unchanged or not imported."
                }
              },
              "required": [
                "scanned",
                "created",
                "updated",
                "skipped"
              ],
              "additionalProperties": false,
              "description": "Task records included in the import."
            }
          },
          "required": [],
          "additionalProperties": false,
          "description": "Per-object counts for the import."
        },
        "limitations": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "description": "Stable key identifying this option within its collection; distinct from its display label."
              },
              "reason": {
                "type": "string",
                "enum": [
                  "missing_scope",
                  "no_equivalent",
                  "degraded",
                  "not_available"
                ],
                "description": "Explanation of why this outcome occurred."
              },
              "detail": {
                "type": "string",
                "description": "Additional explanation of the reported result."
              },
              "count": {
                "type": "number",
                "description": "Number of matching items represented by this result."
              }
            },
            "required": [
              "key",
              "reason"
            ],
            "additionalProperties": false
          },
          "description": "Known exclusions or incomplete coverage in this import run."
        },
        "portal": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string",
              "description": "Unique identifier. Use the value returned by a create or list operation."
            },
            "domain": {
              "type": "string",
              "description": "Website hostname, without a scheme or path."
            },
            "currency": {
              "type": "string",
              "description": "Three-letter currency code, such as NOK, SEK or EUR."
            }
          },
          "required": [],
          "additionalProperties": false,
          "description": "Provider account or portal identifier used by this connection."
        }
      },
      "required": [
        "counts",
        "limitations"
      ],
      "additionalProperties": false
    },
    "started_at": {
      "type": "number",
      "description": "Time this work started, in Unix milliseconds."
    },
    "completed_at": {
      "type": [
        "number",
        "null"
      ],
      "description": "Time this work completed, in Unix milliseconds."
    }
  },
  "required": [
    "job_id",
    "status",
    "progress_percent",
    "report",
    "started_at"
  ],
  "additionalProperties": false,
  "examples": [
    {
      "job_id": "e_example",
      "status": "completed",
      "progress_percent": 1,
      "report": {
        "counts": {},
        "limitations": []
      },
      "started_at": 1794301200000
    }
  ]
}
```

