> ## 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.

# Satellite & Crop Monitoring

> Register fields for satellite monitoring, retrieve NDVI, NDRE, and RGB imagery from Sentinel-2 and PlanetScope, and manage monitoring subscriptions.

Use the satellite service to register geometries for monitoring, retrieve processed image captures, and manage Planet subscriptions or reprocessing. This page is the endpoint reference for Sentinel and Planet imagery once you already understand the product-level behavior.

For conceptual background, see [Satellite Imagery Overview](/satellite/overview).

## Base URL

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

## Endpoints

| Endpoint                                                            | Method                                                             | Path                                         |
| ------------------------------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------- |
| [Get all satellite fields](#get-all-satellite-fields)               | <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>    | `/fields`                                    |
| [Get a satellite field](#get-a-satellite-field)                     | <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>    | `/fields/{id}`                               |
| [Get images of satellite field](#get-images-of-satellite-field)     | <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>    | `/fields/{id}/processes`                     |
| [Get an image of satellite field](#get-an-image-of-satellite-field) | <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>    | `/fields/{id}/processes/{processId}`         |
| [Create a satellite field](#create-a-satellite-field)               | <span style={{fontWeight: 'bold', color: '#e5a00d'}}>POST</span>   | `/fields`                                    |
| [Delete a satellite field](#delete-a-satellite-field)               | <span style={{fontWeight: 'bold', color: '#dc2626'}}>DELETE</span> | `/fields/{id}`                               |
| [Get subscription for Planet](#get-subscription-for-planet)         | <span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span>    | `/fields/{id}/subscription`                  |
| [Reprocess satellite images](#reprocess-satellite-images)           | <span style={{fontWeight: 'bold', color: '#e5a00d'}}>POST</span>   | `/fields/{id}/process/{processId}/reprocess` |

<Warning>Planet imagery is billed per area processed. Every satellite field with `Planet` in its `providers` array consumes quota when new imagery is processed. Use a small test geometry when validating your integration.</Warning>

***

### Get all satellite fields

<span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span> `/fields`

Returns a paginated list of satellite fields for the authenticated API owner.

#### Parameters

| Parameter | Type    | Description                                                                                                            |
| --------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
| `page`    | integer | Page number (default `0`).                                                                                             |
| `size`    | integer | Page size (default `20`, max `100`).                                                                                   |
| `sort`    | string  | Sorting order. Valid fields: `createdAt`, `providers`, `externalId`. Append `,asc` or `,desc` (e.g. `createdAt,desc`). |

#### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/satellite/api/fields?page=0&size=10&sort=createdAt,desc'
  ```

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields"
  headers = {"Authorization": f"Bearer {TOKEN}"}
  params = {"page": 0, "size": 10, "sort": "createdAt,desc"}

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

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

  const endpoint = 'https://api.withleaf.io/services/satellite/api/fields'
  const headers = { Authorization: `Bearer ${TOKEN}` }
  const params = { page: 0, size: 10, sort: 'createdAt,desc' }

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

#### Response

```json theme={null}
[
  {
    "id": "b2a3c4d5-e6f7-4890-abcd-ef1234567890",
    "externalId": "north-quarter",
    "geometry": {
      "type": "MultiPolygon",
      "coordinates": [[[
        [-93.48821, 41.77137],
        [-93.48817, 41.77143],
        [-93.48821, 41.76068],
        [-93.48821, 41.77137]
      ]]]
    },
    "providers": ["Sentinel"],
    "createdAt": "2023-07-21T13:01:11Z"
  }
]
```

***

### Get a satellite field

<span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span> `/fields/{id}`

Returns a single satellite field by ID.

#### Parameters

| Parameter | Type        | Description             |
| --------- | ----------- | ----------------------- |
| `id`      | path (UUID) | The satellite field ID. |

#### Request

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

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields/{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/satellite/api/fields/{id}'
  const headers = { Authorization: `Bearer ${TOKEN}` }

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

#### Response

Returns a single satellite field object (same shape as the objects in the [Get all satellite fields](#get-all-satellite-fields) response).

***

### Get images of satellite field

<span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span> `/fields/{id}/processes`

Returns a paginated list of processed satellite images for the specified field. Each process represents a single capture date and contains one or more image types (NDVI, RGB, etc.).

#### Parameters

| Parameter                 | Type        | Description                                                              |
| ------------------------- | ----------- | ------------------------------------------------------------------------ |
| `id`                      | path (UUID) | The satellite field ID.                                                  |
| `startDate`               | string      | ISO 8601 date. Returns images captured on or after this date.            |
| `endDate`                 | string      | ISO 8601 date. Returns images captured on or before this date.           |
| `startProcessedTimestamp` | string      | ISO 8601 timestamp. Returns images processed on or after this time.      |
| `endProcessedTimestamp`   | string      | ISO 8601 timestamp. Returns images processed on or before this time.     |
| `maxClouds`               | number      | Maximum cloud percentage to include, from `0.0` to `100.0`.              |
| `minCoverage`             | number      | Minimum field coverage percentage to include, from `0.0` to `100.0`.     |
| `provider`                | string      | Filter by provider: `sentinel` or `planet`.                              |
| `page`                    | integer     | Page number (default `0`).                                               |
| `size`                    | integer     | Page size (default `20`, max `100`).                                     |
| `sort`                    | string      | Sorting order with optional `,asc` or `,desc` suffix (e.g. `date,desc`). |

#### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/satellite/api/fields/{id}/processes?startDate=2020-09-07&endDate=2020-09-10&provider=sentinel&page=0&size=10&sort=date,desc'
  ```

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields/{id}/processes"
  headers = {"Authorization": f"Bearer {TOKEN}"}
  params = {
      "startDate": "2020-09-07",
      "endDate": "2020-09-10",
      "provider": "sentinel",
      "page": 0,
      "size": 10,
      "sort": "date,desc",
  }

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

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

  const endpoint = 'https://api.withleaf.io/services/satellite/api/fields/{id}/processes'
  const headers = { Authorization: `Bearer ${TOKEN}` }
  const params = {
    startDate: '2020-09-07',
    endDate: '2020-09-10',
    provider: 'sentinel',
    page: 0,
    size: 10,
    sort: 'date,desc',
  }

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

#### Response

```json theme={null}
[
  {
    "id": "c3d4e5f6-a7b8-4901-cdef-ab1234567890",
    "date": "2020-09-07T19:03:57.882Z",
    "clouds": 0,
    "provider": "sentinel",
    "status": "SUCCESS",
    "coverage": 100,
    "images": [
      {
        "url": "https://satellite-imagery.withleaf.io/ndvi/c3d4e5f6.png",
        "downloadUrl": "https://satellite-imagery.withleaf.io/ndvi/c3d4e5f6.tif",
        "type": "NDVI"
      },
      {
        "url": "https://satellite-imagery.withleaf.io/rgb/c3d4e5f6.png",
        "downloadUrl": "https://satellite-imagery.withleaf.io/rgb/c3d4e5f6.tif",
        "type": "RGB"
      }
    ],
    "processedTimestamp": "2020-09-07T19:03:58.881731Z"
  }
]
```

***

### Get an image of satellite field

<span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span> `/fields/{id}/processes/{processId}`

Returns a single satellite image process by ID.

#### Parameters

| Parameter   | Type        | Description             |
| ----------- | ----------- | ----------------------- |
| `id`        | path (UUID) | The satellite field ID. |
| `processId` | path (UUID) | The process ID.         |

#### Request

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

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields/{id}/processes/{processId}"
  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/satellite/api/fields/{id}/processes/{processId}'
  const headers = { Authorization: `Bearer ${TOKEN}` }

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

#### Response

Returns a single process object (same shape as the objects in the [Get images of satellite field](#get-images-of-satellite-field) response).

***

### Create a satellite field

<span style={{fontWeight: 'bold', color: '#eab308'}}>POST</span> `/fields`

Creates a satellite field and begins imagery processing. Once created, Leaf fetches available satellite imagery for the geometry from the specified providers.

#### Parameters

| Parameter    | Type                            | Description                                                                                                  |
| ------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `externalId` | string (required)               | Your identifier for the field.                                                                               |
| `geometry`   | GeoJSON MultiPolygon (required) | The field boundary.                                                                                          |
| `providers`  | array of strings (optional)     | Satellite providers to enable. Accepted values: `sentinel`, `planet`. Defaults to `["sentinel"]` if omitted. |

<Tip>Start with `sentinel` for development and testing. Add `planet` when you need higher-resolution imagery in production.</Tip>

#### Request body

```json theme={null}
{
  "externalId": "north-quarter",
  "geometry": {
    "type": "MultiPolygon",
    "coordinates": [[[
      [-93.48821, 41.77137],
      [-93.48817, 41.77143],
      [-93.48821, 41.76068],
      [-93.48821, 41.77137]
    ]]]
  },
  "providers": ["sentinel"]
}
```

#### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    -H 'Content-Type: application/json' \
    -d '{"externalId":"north-quarter","geometry":{"type":"MultiPolygon","coordinates":[[[[-93.48821,41.77137],[-93.48817,41.77143],[-93.48821,41.76068],[-93.48821,41.77137]]]]},"providers":["sentinel"]}' \
    'https://api.withleaf.io/services/satellite/api/fields'
  ```

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields"
  headers = {"Authorization": f"Bearer {TOKEN}"}

  data = {
      "externalId": "north-quarter",
      "geometry": {
          "type": "MultiPolygon",
          "coordinates": [[[[-93.48821, 41.77137], [-93.48817, 41.77143], [-93.48821, 41.76068], [-93.48821, 41.77137]]]]
      },
      "providers": ["sentinel"]
  }

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

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

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

  const data = {
    externalId: 'north-quarter',
    geometry: {
      type: 'MultiPolygon',
      coordinates: [[[[-93.48821, 41.77137], [-93.48817, 41.77143], [-93.48821, 41.76068], [-93.48821, 41.77137]]]]
    },
    providers: ['sentinel']
  }

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

#### Response

```json theme={null}
{
  "id": "b2a3c4d5-e6f7-4890-abcd-ef1234567890",
  "externalId": "north-quarter",
  "geometry": {
    "type": "MultiPolygon",
    "coordinates": [[[
      [-93.48821, 41.77137],
      [-93.48817, 41.77143],
      [-93.48821, 41.76068],
      [-93.48821, 41.77137]
    ]]]
  },
  "providers": ["sentinel"],
  "createdAt": "2023-07-21T13:01:11Z"
}
```

***

### Delete a satellite field

<span style={{fontWeight: 'bold', color: '#dc2626'}}>DELETE</span> `/fields/{id}`

Deletes a satellite field and stops all future imagery processing for it.

#### Parameters

| Parameter | Type        | Description             |
| --------- | ----------- | ----------------------- |
| `id`      | path (UUID) | The satellite field ID. |

#### Request

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

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields/{id}"
  headers = {"Authorization": f"Bearer {TOKEN}"}

  response = requests.delete(endpoint, headers=headers)
  print(response.status_code)
  ```

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

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

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

***

### Get subscription for Planet

<span style={{fontWeight: 'bold', color: '#16a34a'}}>GET</span> `/fields/{id}/subscription`

Returns the Planet subscription status for a satellite field. This endpoint only applies to fields that have `Planet` in their `providers` array.

#### Parameters

| Parameter | Type        | Description             |
| --------- | ----------- | ----------------------- |
| `id`      | path (UUID) | The satellite field ID. |

#### Request

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

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields/{id}/subscription"
  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/satellite/api/fields/{id}/subscription'
  const headers = { Authorization: `Bearer ${TOKEN}` }

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

#### Response

```json theme={null}
{
  "fieldId": "b2a3c4d5-e6f7-4890-abcd-ef1234567890",
  "provider": "Planet",
  "status": "ACTIVE"
}
```

***

### Reprocess satellite images

<span style={{fontWeight: 'bold', color: '#eab308'}}>POST</span> `/fields/{id}/process/{processId}/reprocess`

Triggers reprocessing for a specific satellite image. Use this if a process failed or if you need updated imagery outputs.

#### Parameters

| Parameter   | Type        | Description                  |
| ----------- | ----------- | ---------------------------- |
| `id`        | path (UUID) | The satellite field ID.      |
| `processId` | path (UUID) | The process ID to reprocess. |

#### Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    -H 'Authorization: Bearer YOUR_TOKEN' \
    'https://api.withleaf.io/services/satellite/api/fields/{id}/process/{processId}/reprocess'
  ```

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

  TOKEN = "YOUR_TOKEN"
  endpoint = "https://api.withleaf.io/services/satellite/api/fields/{id}/process/{processId}/reprocess"
  headers = {"Authorization": f"Bearer {TOKEN}"}

  response = requests.post(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/satellite/api/fields/{id}/process/{processId}/reprocess'
  const headers = { Authorization: `Bearer ${TOKEN}` }

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