# Inventory Import

The Inventory Import API allows external systems to create and update inventory records in Claret. The API supports two methods: JSON payloads for direct integrations and CSV file uploads with optional field mapping.

As with all Claret API endpoints, the Inventory Import API requires token authentication. For instructions on how to retrieve and pass through the authentication token, please refer to the [Authentication](https://docs.claret.app/apis/authentication) documentation.

{% hint style="info" %}
All API documentation herein contains a `{tenant}` section of the URL path. These should always be replaced with the name of the actual tenant making the API call (i.e., `demo`, `yourcompany`, etc.)
{% endhint %}

### POST Inventory Import

<mark style="color:green;">`POST`</mark> `https://plan.claret.app/{tenant}/api/v1/inventory/import/process`

Import inventory records using either JSON payload or CSV file upload.

**Rate Limits:**

* Maximum 1000 records per request

#### Request Methods

The API supports two methods for importing inventory data:

| Method          | Content-Type          | Response Code | Job Monitoring                  |
| --------------- | --------------------- | ------------- | ------------------------------- |
| JSON Payload    | `application/json`    | 200 OK        | Via UI link only                |
| CSV File Upload | `multipart/form-data` | 202 Accepted  | Via `job_log_id` (programmatic) |

{% hint style="info" %}
**Which method should I use?**

* Use **JSON Payload** for direct API integrations where you construct records programmatically
* Use **CSV File Upload** when exporting data from external systems or when you need programmatic job status monitoring via `job_log_id`
  {% endhint %}

***

## JSON Payload Method

Use this method for direct API integrations where you construct inventory records programmatically.

#### Headers

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer {token}`   |

#### Request Body

| Name                                                                      | Type    | Description                                       |
| ------------------------------------------------------------------------- | ------- | ------------------------------------------------- |
| source<mark style="color:red;">\*</mark>                                  | string  | Must be `"api"` for API requests                  |
| arguments<mark style="color:red;">\*</mark>                               | object  | Processing options (see below)                    |
| payload<mark style="color:red;">\*</mark>                                 | array   | Array of inventory records to import              |
| (arguments) allow\_record\_creation<mark style="color:red;">\*</mark>     | boolean | Allow creating new inventory records              |
| (arguments) allow\_record\_update<mark style="color:red;">\*</mark>       | boolean | Allow updating existing records                   |
| (arguments) should\_continue\_on\_error<mark style="color:red;">\*</mark> | boolean | Continue processing if errors occur               |
| (payload) item\_name<mark style="color:red;">\*</mark>                    | string  | Item name (must exist in Claret)                  |
| (payload) bin\_name<mark style="color:red;">\*</mark>                     | string  | Bin name (must exist in Claret)                   |
| (payload) lot\_name<mark style="color:red;">\*</mark>                     | string  | Lot name (must exist in Claret)                   |
| (payload) date\_filled<mark style="color:red;">\*</mark>                  | string  | Date inventory was filled. **Format: YYYY-MM-DD** |
| (payload) quantity<mark style="color:red;">\*</mark>                      | number  | Quantity amount (positive number)                 |
| (payload) uom<mark style="color:red;">\*</mark>                           | string  | Unit of measure (name or abbreviation)            |

{% tabs %}
{% tab title="200: OK Import Started" %}

```json
{
  "message": "Data import process started successfully. You will receive an email notification when the import completes.",
  "job_status_link": "https://plan.claret.app/{tenant}/settings/application-maintenance/job-management/imports/logs/12345"
}
```

{% endtab %}

{% tab title="422: Unprocessable Entity Validation Failed" %}

```json
{
  "status": 0,
  "message": "Validation failed",
  "data": {
    "errors": [
      {
        "row": 1,
        "field": "item_name",
        "value": "INVALID-ITEM",
        "message": "Item with name 'INVALID-ITEM' does not exist in the system"
      }
    ]
  }
}
```

{% endtab %}
{% endtabs %}

#### Example: JSON Payload Request

```bash
curl -X POST "https://plan.claret.app/{tenant}/api/v1/inventory/import/process" \
  -H "Authorization: Bearer {your-token}" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "api",
    "arguments": {
      "allow_record_creation": true,
      "allow_record_update": true,
      "should_continue_on_error": false
    },
    "payload": [
      {
        "item_name": "WIP-2024-CHARD",
        "bin_name": "TANK-A1",
        "lot_name": "LOT-2024-01",
        "date_filled": "2024-03-15",
        "quantity": 5000,
        "uom": "Gallon"
      }
    ]
  }'
```

***

## CSV File Upload Method

Use this method when exporting data from external systems or when you need programmatic job status monitoring.

#### Headers

| Name          | Value                 |
| ------------- | --------------------- |
| Content-Type  | `multipart/form-data` |
| Authorization | `Bearer {token}`      |

#### Form Fields

| Name                                        | Type        | Description                                      |
| ------------------------------------------- | ----------- | ------------------------------------------------ |
| file<mark style="color:red;">\*</mark>      | file        | CSV file to upload (max 10MB)                    |
| arguments<mark style="color:red;">\*</mark> | JSON string | Processing options (see below)                   |
| field\_mappings                             | JSON string | Required when `headers_match_exactly` is `false` |

#### Arguments Object

| Name                                                          | Type    | Description                                                  |
| ------------------------------------------------------------- | ------- | ------------------------------------------------------------ |
| headers\_match\_exactly                                       | boolean | Set `true` if CSV headers match staging column names exactly |
| allow\_record\_creation<mark style="color:red;">\*</mark>     | boolean | Allow creating new inventory records                         |
| allow\_record\_update<mark style="color:red;">\*</mark>       | boolean | Allow updating existing records                              |
| should\_continue\_on\_error<mark style="color:red;">\*</mark> | boolean | Continue processing if errors occur                          |

### Option A: CSV with Exact Headers

When your CSV file has headers that exactly match Claret's expected column names.

**Required CSV Headers:**

* `item_name`
* `bin_name`
* `lot_name`
* `date_filled`
* `quantity`
* `uom`

```bash
curl -X POST "https://plan.claret.app/{tenant}/api/v1/inventory/import/process" \
  -H "Authorization: Bearer {your-token}" \
  -F "file=@inventory.csv" \
  -F 'arguments={"headers_match_exactly":true,"allow_record_creation":true,"allow_record_update":true,"should_continue_on_error":false}'
```

### Option B: CSV with Custom Headers + Field Mapping

When your CSV file has custom headers (e.g., exports from other systems), provide a mapping to Claret's column names.

**Field Mappings Object:** Maps your CSV headers to Claret's staging column names.

```json
{
  "Your CSV Header": "claret_column_name"
}
```

**Valid Claret Column Names:**

* `item_name`
* `bin_name`
* `lot_name`
* `date_filled`
* `quantity`
* `uom`

```bash
curl -X POST "https://plan.claret.app/{tenant}/api/v1/inventory/import/process" \
  -H "Authorization: Bearer {your-token}" \
  -F "file=@inventory_export.csv" \
  -F 'arguments={"headers_match_exactly":false,"allow_record_creation":true,"allow_record_update":true,"should_continue_on_error":false}' \
  -F 'field_mappings={"Product Name":"item_name","Tank":"bin_name","Lot Number":"lot_name","Date":"date_filled","Volume":"quantity","Unit":"uom"}'
```

{% tabs %}
{% tab title="202: Accepted File Upload Started" %}

```json
{
  "message": "Data import process started successfully. Check job status for updates.",
  "job_log_id": 12345,
  "job_status_link": "https://plan.claret.app/{tenant}/settings/application-maintenance/job-management/imports/logs/12345"
}
```

{% endtab %}

{% tab title="422: Unprocessable Entity Header Mismatch" %}

```json
{
  "status": 0,
  "message": "CSV headers do not match expected format. Expected headers: item_name, bin_name, lot_name, date_filled, quantity, uom. Found headers: Product, Bin, Lot, Fill Date, Qty, Unit. Please set headers_match_exactly=false and provide field_mappings, or update your CSV to use the expected header names.",
  "data": null
}
```

{% endtab %}

{% tab title="422: Unprocessable Entity Invalid File" %}

```json
{
  "status": 0,
  "message": "Invalid file type. Only CSV files are allowed.",
  "data": null
}
```

{% endtab %}
{% endtabs %}

***

### Checking Job Status

For CSV file uploads, use the returned `job_log_id` to programmatically monitor import progress.

See the [Job Status](https://docs.claret.app/apis/public-apis/job-status) documentation for details on the status endpoint.

```bash
curl -X GET "https://plan.claret.app/{tenant}/api/v1/imports/status/12345" \
  -H "Authorization: Bearer {your-token}"
```

***

### Pre-requisites

Before importing inventory via the API, ensure these entities exist in Claret:

| Entity | Requirement                                         |
| ------ | --------------------------------------------------- |
| Items  | Must exist with exact name matching `item_name`     |
| Bins   | Must exist with exact name matching `bin_name`      |
| Lots   | Must exist with exact name matching `lot_name`      |
| UOMs   | Must exist with name or abbreviation matching `uom` |

{% hint style="info" %}
All entity matches are **case-sensitive**. Ensure the names in your import data exactly match the values configured in Claret.
{% endhint %}

***

### Common Errors

| Error Message                                    | Cause                                            | Solution                                                                |
| ------------------------------------------------ | ------------------------------------------------ | ----------------------------------------------------------------------- |
| `Invalid payload structure`                      | Single object instead of array                   | Wrap record in array: `[{...}]`                                         |
| `Item with name '...' does not exist`            | Item name mismatch                               | Verify item exists in Claret, check exact name                          |
| `Bin with name '...' does not exist`             | Bin name mismatch                                | Verify bin exists in Claret, check exact name                           |
| `Invalid file type. Only CSV files are allowed.` | Non-CSV file uploaded                            | Upload a valid CSV file (.csv extension)                                |
| `File size exceeds maximum allowed size of 10MB` | File too large                                   | Split into multiple smaller files                                       |
| `Field mappings are required`                    | Missing field\_mappings when headers don't match | Provide field\_mappings parameter                                       |
| `Invalid mapping target`                         | Invalid Claret column name in mapping            | Use only: item\_name, bin\_name, lot\_name, date\_filled, quantity, uom |
