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

# Machine Files & Upload

> List, retrieve, and upload machine files from equipment monitors. Manage batch uploads and track processing status through Leaf's conversion pipeline.

Use the files endpoints to inspect individual machine files after Leaf ingests them from a provider or manual upload. This page also covers batch upload endpoints, processing-status inspection, and helper endpoints for uncovered or outside-field data.

For conceptual background, see [Machine Data Overview](/machine-data/overview) and [Uploading Files](/machine-data/uploading-files).

## Base URL

```
https://api.withleaf.io/services/operations/api
```

## Endpoints

### Machine files

| Method                                                           | Path                              | Description                                                   |
| ---------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------- |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files`                          | [Get all machine files](#get-all-machine-files)               |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}`                     | [Get a machine file](#get-a-machine-file)                     |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}/summary`             | [Get file summary](#get-file-summary)                         |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}/standardGeoparquet`  | [Get file standardGeoParquet](#get-file-standardgeoparquet)   |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}/polygonGeoparquet`   | [Get file polygonGeoParquet](#get-file-polygongeoparquet)     |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}/units`               | [Get file units](#get-file-units)                             |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}/status`              | [Get file status](#get-file-status)                           |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/{id}/outsideFieldGeojson` | [Get file outsideFieldGeoJSON](#get-file-outsidefieldgeojson) |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/outsideFieldGeojson`      | [Get all outsideFieldGeoJSON](#get-all-outsidefieldgeojson)   |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/files/uncoveredFiles`           | [Get uncovered files](#get-uncovered-files)                   |
| <span style={{fontWeight: 'bold', color: '#e5a00d'}}>POST</span> | `/files/merge`                    | [Merge files](#merge-files)                                   |

### Batch upload

| Method                                                           | Path                 | Description                                       |
| ---------------------------------------------------------------- | -------------------- | ------------------------------------------------- |
| <span style={{fontWeight: 'bold', color: '#e5a00d'}}>POST</span> | `/batch`             | [Upload a file](#upload-a-file)                   |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/batch/{id}`        | [Get a batch](#get-a-batch)                       |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/batch`             | [Get all batches](#get-all-batches)               |
| <span style={{fontWeight: 'bold', color: '#e5a00d'}}>PUT</span>  | `/batch/{id}/retry`  | [Retry a batch](#retry-a-batch)                   |
| <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>  | `/batch/{id}/status` | [Get batch files status](#get-batch-files-status) |

<Info>
  To access machine files, you need a Leaf user with valid provider credentials. See the Users and Integrations documentation to set up credentials.
</Info>

***

## Get all machine files

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files`

Returns a paginated list of machine files for the authenticated API owner.

### Parameters

| Parameter            | Type    | Description                                                                                                                                                                           |
| -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `leafUserId`         | string  | UUID of a Leaf user                                                                                                                                                                   |
| `provider`           | string  | `CNHI`, `JohnDeere`, `Trimble`, `ClimateFieldView`, `AgLeader`, `RavenSlingshot`, `Stara`, or `Leaf`                                                                                  |
| `status`             | string  | `processed`, `failed`, or `processing`                                                                                                                                                |
| `origin`             | string  | `provider`, `automerged`, `merged`, or `uploaded`                                                                                                                                     |
| `organizationId`     | string  | Provider organization ID (John Deere only)                                                                                                                                            |
| `batchId`            | string  | UUID of the upload batch                                                                                                                                                              |
| `fileId`             | string  | Filter by a specific file ID                                                                                                                                                          |
| `fileFormat`         | string  | Filter by file format (e.g., `SHAPEFILE`, `CN1`, `ISO11783`, `AGDATA`)                                                                                                                |
| `createdTime`        | string  | ISO 8601 timestamp. Returns files created on or after this time                                                                                                                       |
| `startTime`          | string  | ISO 8601 timestamp. Returns files with operations starting on or after this time                                                                                                      |
| `updatedTime`        | string  | ISO 8601 timestamp. Returns files updated on or after this time                                                                                                                       |
| `endTime`            | string  | ISO 8601 timestamp. Returns files with operations ending on or before this time                                                                                                       |
| `operationStartTime` | string  | ISO 8601 timestamp. Same as `startTime` (alternative parameter name)                                                                                                                  |
| `operationEndTime`   | string  | ISO 8601 timestamp. Same as `endTime` (alternative parameter name)                                                                                                                    |
| `operationType`      | string  | `applied`, `planted`, `harvested`, or `tillage`                                                                                                                                       |
| `minArea`            | number  | Minimum operation area in square meters                                                                                                                                               |
| `providerFileId`     | string  | The file ID from the original provider                                                                                                                                                |
| `standard`           | boolean | Filter by whether the file has a standardGeojson                                                                                                                                      |
| `page`               | integer | Page number (default `0`)                                                                                                                                                             |
| `size`               | integer | Page size (max `100`)                                                                                                                                                                 |
| `sort`               | string  | Sort order. Valid fields: `id`, `fileName`, `createdTime`, `updatedTime`, `origin`, `leafUserId`, `sizeInBytes`, `provider`, `organizationId`, `fileFormat`. Append `,asc` or `,desc` |

<Info>The default page size is 20 when `page` and `size` are not set.</Info>

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files?leafUserId=UUID'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers, params={'leafUserId': 'UUID'})
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers, params: { leafUserId: 'UUID' } })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

***

## Get a machine file

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}`

Returns a single machine file by its UUID.

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

***

## Get file summary

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}/summary`

Returns the summary for a machine file, containing aggregated statistics for the file's data points.

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}/summary'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/summary'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/summary'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

***

## Get file standardGeoParquet

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}/standardGeoparquet`

Returns a URL to the standard GeoParquet file.

<Tip>You must enable the `enableGeoparquetOutput` configuration to use this endpoint.</Tip>

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}/standardGeoparquet'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/standardGeoparquet'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/standardGeoparquet'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

***

## Get file polygonGeoParquet

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}/polygonGeoparquet`

Returns a URL to the polygon GeoParquet file.

<Tip>You must enable the `enableGeoparquetOutput` configuration to use this endpoint.</Tip>

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}/polygonGeoparquet'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/polygonGeoparquet'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/polygonGeoparquet'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

***

## Get file units

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}/units`

Returns the property-to-unit mapping for the machine file. Properties vary by operation type but use standardized keys across providers.

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}/units'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/units'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/units'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

***

## Get file status

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}/status`

Returns the processing status for each step of Leaf's pipeline for the specified machine file.

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}/status'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/status'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/status'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "originalFile":      { "status": "processed", "message": "ok" },
  "rawGeojson":        { "status": "processed", "message": "ok" },
  "standardGeojson":   { "status": "processed", "message": "ok" },
  "filteredGeojson":   { "status": "processed", "message": "ok" },
  "propertiesPNGs":    { "status": "processed", "message": "ok" },
  "zippedPNGs":        { "status": "processed", "message": "ok" },
  "summary":           { "status": "processed", "message": "ok" },
  "units":             { "status": "processed", "message": "ok" }
}
```

Each key represents a pipeline step. The `status` value is one of:

| Status      | Meaning                                                                               |
| ----------- | ------------------------------------------------------------------------------------- |
| `processed` | Step completed successfully                                                           |
| `failed`    | Step failed — see `message` for details                                               |
| `skipped`   | Step was skipped due to an earlier failure or a configuration that prevents execution |

### Common failure messages

| Message                                               | Cause                                                                                                                                                      |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `no points passed the filter`                         | All data points were removed during cleanup. The file may have 0 valid points. Toggle the `cleanupStandardGeojson` configuration to control this behavior. |
| `unsupported operation type: {type}`                  | The detected operation type is not one of the four supported types (planting, application, harvest, tillage).                                              |
| `missing required properties: {properties}`           | One or more required properties from Leaf's standard schema were not found in the file.                                                                    |
| `Failed to convert file on provider batch processing` | Leaf could not extract valid data from the provider file. Verify the file structure and format.                                                            |

***

## Get file outsideFieldGeoJSON

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/{id}/outsideFieldGeojson`

Returns a GeoJSON file containing data points from the machine file that do not fall within any field boundary.

<Tip>Requires both `splitOperationsByField` and `enableOutsideFieldGeojson` configurations to be enabled.</Tip>

### Parameters

| Parameter | Type | Description      |
| --------- | ---- | ---------------- |
| `id`      | path | UUID of the file |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/{id}/outsideFieldGeojson'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/outsideFieldGeojson'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/{id}/outsideFieldGeojson'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "fields": ["uuid"],
  "featureCount": 21,
  "outsideFieldGeojson": "URL",
  "downloadOutsideFieldGeojson": "URL"
}
```

***

## Get all outsideFieldGeoJSON

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/outsideFieldGeojson`

Returns a list of all machine files that have data points outside field boundaries.

<Tip>Requires both `splitOperationsByField` and `enableOutsideFieldGeojson` configurations to be enabled.</Tip>

### Parameters

| Parameter    | Type    | Description                  |
| ------------ | ------- | ---------------------------- |
| `leafUserId` | string  | UUID of a Leaf user          |
| `page`       | integer | Page number (default `0`)    |
| `size`       | integer | Page size (max `100`)        |
| `sort`       | string  | Sort order (e.g., `id,desc`) |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/outsideFieldGeojson?leafUserId=UUID'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/outsideFieldGeojson'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers, params={'leafUserId': 'UUID'})
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/outsideFieldGeojson'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers, params: { leafUserId: 'UUID' } })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
[
  {
    "id": "uuid",
    "fields": ["uuid"],
    "featureCount": 21,
    "outsideFieldGeojson": "URL",
    "downloadOutsideFieldGeojson": "URL"
  }
]
```

***

## Get uncovered files

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/files/uncoveredFiles`

Returns a list of machine file IDs that did not generate field operations because they do not intersect with any field boundary.

### Parameters

| Parameter    | Type   | Description                       |
| ------------ | ------ | --------------------------------- |
| `leafUserId` | string | **Required.** UUID of a Leaf user |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/files/uncoveredFiles?leafUserId=UUID'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/uncoveredFiles'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers, params={'leafUserId': 'UUID'})
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/uncoveredFiles'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers, params: { leafUserId: 'UUID' } })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "files": [
    "c3ad6c7b-19b8-4cd7-580a-dfab82043465",
    "c3ad6c7b-c472-49e9-aab2-7ad222843465"
  ]
}
```

***

## Merge files

<span style={{color: 'orange', fontWeight: 'bold'}}>POST</span> `/files/merge`

Merges two or more machine files into a single file. Processing is asynchronous — poll the returned file ID to check status.

All files must belong to the same Leaf user, share the same operation type, and have `processed` status.

### Request body

```json theme={null}
{
  "ids": ["fileId1", "fileId2"]
}
```

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    -H 'Content-Type: application/json' \
    -d '{"ids": ["fileId1", "fileId2"]}' \
    'https://api.withleaf.io/services/operations/api/files/merge'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/files/merge'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.post(endpoint, headers=headers, json={'ids': ['fileId1', 'fileId2']})
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/files/merge'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.post(endpoint, { ids: ['fileId1', 'fileId2'] }, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "id": "uuid",
  "status": "SENT_TO_MERGE"
}
```

***

## Upload a file

<span style={{color: 'orange', fontWeight: 'bold'}}>POST</span> `/batch`

Uploads a `.zip` file containing operation data. Leaf detects the files inside the archive, creates machine file entries, and processes them asynchronously.

### Parameters

| Parameter    | Type   | Description                                                                                                                 |
| ------------ | ------ | --------------------------------------------------------------------------------------------------------------------------- |
| `leafUserId` | string | **Required.** UUID of the Leaf user                                                                                         |
| `provider`   | string | **Required.** `Other`, `Leaf`, `ClimateFieldView`, `CNHI`, `JohnDeere`, `Trimble`, `AgLeader`, `RavenSlingshot`, or `Stara` |
| `fileFormat` | string | Optional. Hints at the file format inside the archive                                                                       |

<Warning>Maximum upload size is 3 GB.</Warning>

<Note>
  Set `provider` to `Other` if you are unsure of the format. Leaf auto-detects files from supported providers.
</Note>

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    -F 'file=@data.zip' \
    'https://api.withleaf.io/services/operations/api/batch?leafUserId=UUID&provider=JohnDeere'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/batch'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  files = {'file': open('data.zip', 'rb')}
  params = {'leafUserId': 'UUID', 'provider': 'JohnDeere'}

  response = requests.post(endpoint, headers=headers, files=files, params=params)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const FormData = require('form-data')
  const fs = require('fs')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/batch'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }
  const params = { leafUserId: 'UUID', provider: 'JohnDeere' }

  const form = new FormData()
  form.append('file', fs.createReadStream('data.zip'))

  axios.post(endpoint, form, { headers: { ...headers, ...form.getHeaders() }, params })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "id": "996aea67-52bc-4d4b-9b77-028756dc0ee9",
  "leafUserId": "ede8f781-1d55-4b2d-83a1-6785ddab6e1d",
  "fileName": "data.zip",
  "size": 8652951,
  "provider": "JohnDeere",
  "status": "RECEIVED",
  "uploadTimestamp": "2021-03-12T19:50:55.567755Z"
}
```

### Batch status values

| Status      | Meaning                                                               |
| ----------- | --------------------------------------------------------------------- |
| `RECEIVED`  | Default state after upload                                            |
| `PROCESSED` | All files in the batch were processed and at least one succeeded      |
| `FAILED`    | No files in the batch succeeded. Check `statusDetails` for the reason |

***

## Get a batch

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/batch/{id}`

Returns a single batch upload by its UUID, including the list of generated machine file IDs.

### Parameters

| Parameter | Type | Description       |
| --------- | ---- | ----------------- |
| `id`      | path | UUID of the batch |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/batch/{id}'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/batch/{id}'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/batch/{id}'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "id": "9b561906-efac-43a3-9378-641e3698da5d",
  "leafUserId": "1481bc9b-cdc7-45c1-9f0e-592da6306dfe",
  "provider": "Other",
  "status": "PROCESSED",
  "leafFiles": [
    "f14203df-4144-43b7-a383-2ed321f395ce",
    "810b1475-cb49-437b-8658-d29038ce2fa4"
  ]
}
```

***

## Get all batches

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/batch`

Returns a paginated list of batch uploads.

### Parameters

| Parameter          | Type    | Description                                                          |
| ------------------ | ------- | -------------------------------------------------------------------- |
| `leafUserId`       | string  | UUID of a Leaf user                                                  |
| `status`           | string  | `RECEIVED`, `PROCESSED`, or `FAILED`                                 |
| `uploadStartTime`  | string  | ISO 8601 timestamp. Returns batches uploaded on or after this time   |
| `uploadEndTime`    | string  | ISO 8601 timestamp. Returns batches uploaded on or before this time  |
| `processStartTime` | string  | ISO 8601 timestamp. Returns batches processed on or after this time  |
| `processEndTime`   | string  | ISO 8601 timestamp. Returns batches processed on or before this time |
| `page`             | integer | Page number (default `0`)                                            |
| `size`             | integer | Page size (max `100`)                                                |
| `sort`             | string  | Sort order (e.g., `uploadTimestamp,desc`)                            |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/batch'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/batch'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/batch'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
[
  {
    "id": "9e47ae29-6a84-4a9c-9e5f-01802f6dceea",
    "leafUserId": "5ded9409-c99f-4379-9173-c01b1631f274",
    "provider": "Other",
    "status": "PROCESSED",
    "leafFiles": [
      "74d5aeb6-9a0e-43c6-986c-a5f17eecbddc",
      "475fcad3-b534-409d-8c8b-cec4dabd1b8b"
    ]
  }
]
```

***

## Retry a batch

<span style={{color: 'orange', fontWeight: 'bold'}}>PUT</span> `/batch/{id}/retry`

Retries processing for a batch upload. Only reprocesses the files that did not succeed previously — existing converted files are not affected.

### Parameters

| Parameter | Type | Description       |
| --------- | ---- | ----------------- |
| `id`      | path | UUID of the batch |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/batch/{id}/retry'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/batch/{id}/retry'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.put(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/batch/{id}/retry'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.put(endpoint, {}, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "id": "36d8551f-409d-41f2-94b4-04c9fe16289b",
  "leafUserId": "089bb77b-2415-43df-a246-6c0a5937c774",
  "fileName": "data.zip",
  "size": 8652951,
  "provider": "Other",
  "status": "RECEIVED",
  "uploadTimestamp": "2021-03-12T19:50:55.567755Z"
}
```

***

## Get batch files status

<span style={{color: 'green', fontWeight: 'bold'}}>GET</span> `/batch/{id}/status`

Returns the processing status of each machine file generated from the batch, grouped by status.

### Parameters

| Parameter | Type    | Description               |
| --------- | ------- | ------------------------- |
| `id`      | path    | UUID of the batch         |
| `page`    | integer | Page number (default `0`) |
| `size`    | integer | Page size (max `100`)     |
| `sort`    | string  | Sort order                |

### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/operations/api/batch/{id}/status'
  ```

  ```python Python theme={null}
  import requests

  TOKEN = 'YOUR_TOKEN'
  endpoint = 'https://api.withleaf.io/services/operations/api/batch/{id}/status'
  headers = {'Authorization': f'Bearer {TOKEN}'}

  response = requests.get(endpoint, headers=headers)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios')
  const TOKEN = 'YOUR_TOKEN'

  const endpoint = 'https://api.withleaf.io/services/operations/api/batch/{id}/status'
  const headers = { 'Authorization': `Bearer ${TOKEN}` }

  axios.get(endpoint, { headers })
    .then(res => console.log(res.data))
    .catch(console.error)
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "converted": {
    "leafFiles": [
      "06512392-8d69-4033-8127-4cc62b7176b9",
      "075fd0f6-af1a-433d-ad7a-e3e979179244"
    ]
  },
  "processing": {
    "leafFiles": ["9d22cbca-03ff-47e8-ac66-f6d463d206f4"]
  },
  "failed": {
    "standardGeojson": {
      "leafFiles": ["0abca517-09f2-4d1d-9627-9cd3147e9ec3"],
      "status": "failed",
      "message": "no points passed the filter"
    }
  }
}
```
