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

# Create crop

> Create a crop on a farm and field owned by the authenticated user.

```
POST https://www.wiseyield.co/api/v1/crops
```

### Authentication

Requires a key with the `crops:write` scope. See [Authentication](/authentication).

### Request body

<ParamField body="farmId" type="string" required>
  UUID of the parent farm. Must be owned by the authenticated user.
</ParamField>

<ParamField body="fieldId" type="string" required>
  UUID of the field. Must belong to `farmId`. Required per the [Operations Attachment Principle](/concepts/land-hierarchy).
</ParamField>

<ParamField body="cropType" type="string" required>
  1–200 characters. Free-text crop name (e.g. `"wheat"`, `"date palm"`).
</ParamField>

<ParamField body="plantedArea" type="number | string" required>
  Positive number in the farm's `areaUnit`. Accepts string or number.
</ParamField>

<ParamField body="variety" type="string">
  Up to 200 characters. Free-text variety.
</ParamField>

<ParamField body="adminCropId" type="string">
  UUID linking to the admin Crop Library. Prefer this over `cropType` when the crop is in the catalog.
</ParamField>

<ParamField body="adminCropVarietyId" type="string">
  UUID linking to the admin variety record.
</ParamField>

<ParamField body="plantingDate" type="string">
  ISO 8601 datetime.
</ParamField>

<ParamField body="expectedHarvestDate" type="string">
  ISO 8601 datetime.
</ParamField>

<ParamField body="season" type="string">
  One of `winter`, `summer`, `autumn`, `spring`, `year_round`.
</ParamField>

<ParamField body="seasonYear" type="integer">
  2000–2100.
</ParamField>

<ParamField body="expectedYield" type="number | string">
  Tons.
</ParamField>

<ParamField body="estimatedCost" type="number | string">
  In the farm's `currency`.
</ParamField>

<ParamField body="estimatedRevenue" type="number | string">
  In the farm's `currency`.
</ParamField>

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

<ParamField body="notes" type="string">
  Up to 5,000 characters.
</ParamField>

### Response

Returns the created crop wrapped under `data`. See [List crops](/api-reference/crops/list-crops) for the full field reference.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://www.wiseyield.co/api/v1/crops \
    -H "Authorization: Bearer $WISEYIELD_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "farmId": "11111111-2222-3333-4444-555555555555",
      "fieldId": "88888888-9999-aaaa-bbbb-cccccccccccc",
      "cropType": "date palm",
      "variety": "Medjool",
      "plantedArea": 4.2,
      "plantingDate": "2024-03-15T00:00:00.000Z",
      "season": "spring",
      "seasonYear": 2024,
      "status": "growing"
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch('https://www.wiseyield.co/api/v1/crops', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.WISEYIELD_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      farmId: '11111111-2222-3333-4444-555555555555',
      fieldId: '88888888-9999-aaaa-bbbb-cccccccccccc',
      cropType: 'date palm',
      variety: 'Medjool',
      plantedArea: 4.2,
      status: 'growing',
    }),
  });
  const { data: crop } = await res.json();
  ```

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

  res = requests.post(
      'https://www.wiseyield.co/api/v1/crops',
      headers={
          'Authorization': f"Bearer {os.environ['WISEYIELD_API_KEY']}",
          'Content-Type': 'application/json',
      },
      json={
          'farmId': '11111111-2222-3333-4444-555555555555',
          'fieldId': '88888888-9999-aaaa-bbbb-cccccccccccc',
          'cropType': 'date palm',
          'variety': 'Medjool',
          'plantedArea': 4.2,
          'status': 'growing',
      },
  )
  crop = res.json()['data']
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "data": {
      "id": "33333333-4444-5555-6666-777777777777",
      "farmId": "11111111-2222-3333-4444-555555555555",
      "fieldId": "88888888-9999-aaaa-bbbb-cccccccccccc",
      "cropType": "date palm",
      "variety": "Medjool",
      "plantedArea": "4.2",
      "plantingDate": "2024-03-15T00:00:00.000Z",
      "season": "spring",
      "seasonYear": 2024,
      "status": "growing",
      "createdAt": "2026-05-17T16:00:00.000Z",
      "updatedAt": "2026-05-17T16:00:00.000Z"
    }
  }
  ```

  ```json 400 Validation failed theme={null}
  {
    "error": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": {
      "plantedArea": ["Planted area must be a positive number"],
      "fieldId": ["Valid field ID required"]
    }
  }
  ```

  ```json 400 Field not on farm theme={null}
  {
    "error": "Validation failed",
    "code": "VALIDATION_ERROR",
    "message": "Field not found on this farm"
  }
  ```

  ```json 404 Farm not found theme={null}
  {
    "error": "Not found",
    "code": "NOT_FOUND",
    "message": "Farm not found or access denied"
  }
  ```
</ResponseExample>

## Errors

| Status                    | When                                                                                                     |
| ------------------------- | -------------------------------------------------------------------------------------------------------- |
| `400 VALIDATION_ERROR`    | Schema validation failed (`details` carries per-field messages), OR `fieldId` doesn't belong to `farmId` |
| `401`                     | Missing, malformed, expired, or revoked API key                                                          |
| `403 INSUFFICIENT_SCOPE`  | Key lacks `crops:write` scope                                                                            |
| `404 NOT_FOUND`           | `farmId` not owned by the authenticated user (or soft-deleted)                                           |
| `429 RATE_LIMIT_EXCEEDED` | Per-user rate limit reached                                                                              |
| `5xx`                     | Server error                                                                                             |
