> ## Documentation Index
> Fetch the complete documentation index at: https://www.landbase.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# contacts-import

> Bulk-import contacts from a dataset into the active Landbase account

Bulk-import the contacts in a dataset into the active account under a tag. Start
an import, read a snapshot of its progress, or block until it reaches a terminal
phase.

<Note>
  `contacts-import` is a **platform-mode** command. Before running it:

  1. [`landbase-cli auth login`](/docs/reference/auth) — authenticate the session.
  2. [`landbase-cli account set`](/docs/reference/account) — pick and persist the target account.
  3. Have a `datasetId` from a prior search or agent run — the CLI does not
     produce datasets, so run a search/agent flow first.

  Without an active account the command exits with `No account id...`; pass
  `--account=<id>` per call as an escape hatch.
</Note>

## contacts-import start

Start an import. Reads a JSON body — `{ datasetId, tagName, importId? }` — and
enqueues processing in one call. Pass `-` to read the body from stdin. Returns
`{ importId, runRef }`. With `--watch`, the command stays attached, polls until
the import is terminal, and writes the final status to stdout instead of the
start response.

**Usage**

```bash theme={null}
landbase-cli contacts-import start --json <path|-> [--watch]
```

<ParamField path="--json" type="string" required>
  Path to a JSON file with the import body, or `-` to read it from stdin. Body
  shape: `{ "datasetId": "<dataset-id>", "tagName": "Q2 outreach", "importId"?: 7 }`.
  `datasetId` and `tagName` (1–100 chars) are required; `importId` resumes an
  existing draft.
</ParamField>

**Flags**

| Flag             | Default | Description                                                               |
| ---------------- | ------- | ------------------------------------------------------------------------- |
| `--watch`        | —       | Block until the import is terminal, then print the final status to stdout |
| `--account=<id>` | —       | Override the active account for a single command                          |
| `--verbose`      | —       | Print request/response details to stderr                                  |

***

## contacts-import status

Read one status snapshot. Designed for scripts that drive their own polling loop.

**Usage**

```bash theme={null}
landbase-cli contacts-import status <importId>
```

<ParamField path="importId" type="integer" required>
  The import id returned by `contacts-import start`.
</ParamField>

Prints a lean, stable shape — `{ importId, phase, percent, counts, error }` —
where keys are present in every phase and `null` until known. See
[output schemas](/docs/reference/output-schemas#contacts-import).

***

## contacts-import wait

Block until the import is terminal, then print the final status to stdout. Runs
the same polling loop as `start --watch`, streaming a progress line to stderr per
poll. Backoff schedule: 5s, 10s, then a 20s cap; overall timeout 30 minutes.

**Usage**

```bash theme={null}
landbase-cli contacts-import wait <importId>
```

<ParamField path="importId" type="integer" required>
  The import id to wait on.
</ParamField>

Prefer `wait` (or `start --watch`) over an external polling loop unless you need
a custom cadence. Avoid sub-second polling — it won't return results faster and
may trip rate limits.

***

## Phases

`phase` is the value to branch on. The import is done once it reaches a terminal
phase.

| Phase         | Kind      | Meaning                                                                                             |
| ------------- | --------- | --------------------------------------------------------------------------------------------------- |
| `draft`       | in-flight | Row created but not yet enqueued (rare — `start` enqueues atomically)                               |
| `preparing`   | in-flight | Parsing/validating the dataset; `percent` is `null`                                                 |
| `in_progress` | in-flight | Actively ingesting; `percent` is `0`–`100`                                                          |
| `completed`   | terminal  | Done; `counts` carries the final totals                                                             |
| `partial`     | terminal  | Some rows imported before a later failure; `counts` reflect what landed, `error` carries the reason |
| `failed`      | terminal  | Failed; `error` carries the reason                                                                  |

## Errors

| Code               | Meaning                                                                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `INVALID_INPUT`    | Missing/invalid `--json`, malformed `datasetId`/`tagName`, or a non-integer / zero `importId`.                                                         |
| `AUTH_REQUIRED`    | Run `landbase-cli auth login` first (browser-interactive).                                                                                             |
| `AUTH_FAILED`      | The platform session expired (7-day TTL) — re-login.                                                                                                   |
| `NOT_FOUND`        | The `importId` is unknown or belongs to a different account.                                                                                           |
| `VALIDATION_ERROR` | The back-end rejected the body (e.g. `datasetId` is unknown or not accessible to this account).                                                        |
| `CONFLICT`         | `start` was called again on an `importId` already enqueued. Don't retry — poll `status <importId>`; the in-flight job keeps running.                   |
| `TIMEOUT`          | `wait` / `start --watch` exceeded 30 min still in a non-terminal phase. Resume with `status <importId>` (the id rides in the error's `meta.importId`). |

## Examples

```bash theme={null}
# Fire-and-forget, drive your own poll
echo '{"datasetId":"<dataset-id>","tagName":"Q2 outreach"}' \
  | landbase-cli contacts-import start --json -
# → { "importId": 7, "runRef": "..." }
landbase-cli contacts-import status 7

# Block-and-collect in a single invocation (terminal status to stdout)
echo '{"datasetId":"<dataset-id>","tagName":"Q2 outreach"}' \
  | landbase-cli contacts-import start --json - --watch

# Wait on an existing import
landbase-cli contacts-import wait 7
```

## Related

* [How to import contacts](/docs/how-to/import-contacts)
* [account command reference](/docs/reference/account)
* [datasets command reference](/docs/reference/datasets)
* [Output schemas](/docs/reference/output-schemas#contacts-import)
* [Error codes](/docs/reference/error-codes)
