# Import a CSV file (POST /v1/catalog/imports)

> POST /v1/catalog/imports: Import a CSV file. border.bot API reference (Catalogue).

Source: https://border.bot/docs/api/import-catalog

> Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`.

`POST https://api.border.bot/v1/catalog/imports`

Requires an API key (`Authorization: Bearer bb_live_…`).

Imports (or, by default, checks: `dryRun`) a CSV file of up to 2,000 rows: columns mapped to fields, each row checked and upserted by its `external_id` or `sku`, errors reported per row. Importing the same file again changes nothing. Free.

API key scope: `catalog`.

## Request body (JSON)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `csv` | string | yes |  |
| `filename` | string | no |  |
| `mapping` | object | no |  |
| `dryRun` | boolean | no |  |
| `sourceKind` | string | no |  |
| `connection` | string | no |  |
| `approveCodes` | boolean | no |  |

## Responses

- `200`: What the import did (or would do), with the errors per row. (`CatalogImportResponse`)
- `400`: Invalid input (`invalid_input`). (`Error`)
- `401`: Missing, invalid, revoked or expired API key (`unauthorized`). (`Error`)
- `403`: The API key doesn’t have the `catalog` scope (`forbidden`, `details.reason: "missing_scope"`). (`Error`)
- `429`: Rate limited (`rate_limited`). Retry after `Retry-After` seconds; `RateLimit` says which limit was hit (`r=0`, `t` seconds until its window ends) and `RateLimit-Policy` its quota. (`Error`)
- `500`: Unexpected error (`internal`). (`Error`)

## Example

```bash
curl -X POST 'https://api.border.bot/v1/catalog/imports' \
  -H 'Authorization: Bearer bb_live_...' \
  -H 'Content-Type: application/json' \
  -d '{"csv":"sku,title,origin_country,unit_value,currency,hs_code_us\nBOTTLE-750,Steel water bottle,CN,20,USD,7323930080","filename":"catalogue.csv","dryRun":true}'
```
