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

# Update crop status

> Transition a crop between status states. Setting "harvested" auto-populates actualHarvestDate.

```
PUT https://www.wiseyield.co/api/v1/crops/{id}/status
```

A focused alternative to [PUT /api/v1/crops/{id}](/api-reference/crops/update-crop) when you only need to change `status`. The behavior is identical except for one convenience: transitioning to `harvested` auto-populates `actualHarvestDate` to the current timestamp if it isn't already set.

### Authentication

Requires a key with the `crops:write` scope.

### Path parameters

<ParamField path="id" type="string" required>
  Crop UUID.
</ParamField>

### Request body

<ParamField body="status" type="string" required>
  One of `planned`, `planted`, `growing`, `harvested`, `failed`.
</ParamField>

### Response

Returns the updated crop wrapped under `data`. When transitioning to `harvested`, the returned `actualHarvestDate` reflects the auto-set value.

<RequestExample>
  ```bash cURL theme={null}
  curl -X PUT 'https://www.wiseyield.co/api/v1/crops/33333333-4444-5555-6666-777777777777/status' \
    -H "Authorization: Bearer $WISEYIELD_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "status": "harvested" }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    `https://www.wiseyield.co/api/v1/crops/${cropId}/status`,
    {
      method: 'PUT',
      headers: {
        Authorization: `Bearer ${process.env.WISEYIELD_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ status: 'harvested' }),
    }
  );
  const { data: crop } = await res.json();
  ```

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

  res = requests.put(
      f'https://www.wiseyield.co/api/v1/crops/{crop_id}/status',
      headers={
          'Authorization': f"Bearer {os.environ['WISEYIELD_API_KEY']}",
          'Content-Type': 'application/json',
      },
      json={'status': 'harvested'},
  )
  crop = res.json()['data']
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": {
      "id": "33333333-4444-5555-6666-777777777777",
      "status": "harvested",
      "actualHarvestDate": "2026-05-17T16:10:00.000Z",
      "updatedAt": "2026-05-17T16:10:00.000Z"
    }
  }
  ```

  ```json 400 Invalid status theme={null}
  {
    "error": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": {
      "status": ["Invalid enum value. Expected 'planned' | 'planted' | 'growing' | 'harvested' | 'failed'"]
    }
  }
  ```
</ResponseExample>

## Errors

| Status                    | When                                                                           |
| ------------------------- | ------------------------------------------------------------------------------ |
| `400 INVALID_ID`          | `{id}` is not a valid UUID                                                     |
| `400 VALIDATION_ERROR`    | `status` not in the allowed enum                                               |
| `401`                     | Missing, malformed, expired, or revoked API key                                |
| `403 INSUFFICIENT_SCOPE`  | Key lacks `crops:write` scope                                                  |
| `404 NOT_FOUND`           | Crop doesn't exist, is soft-deleted, or belongs to a farm the user doesn't own |
| `429 RATE_LIMIT_EXCEEDED` | Per-user rate limit reached                                                    |
| `5xx`                     | Server error                                                                   |

## Notes

* This endpoint does **not** trigger the dashboard's harvest-completion notification (which only fires for session-authenticated UI users).
* For full audit history of status transitions, see the dashboard timeline view.
