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

# Farms (v1)

> List and create farms using API key authentication.

The versioned `/api/v1/farms` endpoint is the API-key-authenticated path for managing farms. The list operation returns paginated farms owned by the authenticated user; the create operation persists a new farm under that user.

## List farms

```
GET https://www.wiseyield.co/api/v1/farms
```

### Authentication

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

### Query parameters

<ParamField query="page" type="integer" default="1">
  Page number (≥ 1).
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Results per page (1–100; values above 100 are clamped to 100).
</ParamField>

<ParamField query="status" type="string">
  Filter by farm status: `active`, `inactive`, `archived`, `draft`.
</ParamField>

<ParamField query="sort" type="string" default="createdAt">
  Sort field: `createdAt`, `name`, `totalArea`.
</ParamField>

<ParamField query="order" type="string" default="desc">
  Sort direction: `asc`, `desc`.
</ParamField>

### Response

Returns paginated farm records.

<ResponseField name="data" type="array">
  Array of farm objects.

  <Expandable title="Farm">
    <ResponseField name="id" type="string">UUID identifier.</ResponseField>
    <ResponseField name="name" type="string">Farm name.</ResponseField>
    <ResponseField name="farmType" type="string">One of `commercial`, `organic`, `mixed`, `specialty`.</ResponseField>
    <ResponseField name="primaryUse" type="string">One of `crops`, `livestock`, `mixed`, `research`.</ResponseField>
    <ResponseField name="city" type="string">City.</ResponseField>
    <ResponseField name="country" type="string">Country.</ResponseField>
    <ResponseField name="totalArea" type="string">Numeric string (precision preserved).</ResponseField>
    <ResponseField name="areaUnit" type="string">One of `hectare`, `acre`, `feddan`.</ResponseField>
    <ResponseField name="soilType" type="string">Free-text soil description.</ResponseField>
    <ResponseField name="irrigationSystem" type="string">One of `drip`, `sprinkler`, `flood`, `pivot`, `manual`, `none`.</ResponseField>
    <ResponseField name="status" type="string">One of `active`, `inactive`, `archived`, `draft`.</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 timestamp.</ResponseField>
    <ResponseField name="updatedAt" type="string">ISO 8601 timestamp.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagination" type="object">
  <Expandable title="Pagination">
    <ResponseField name="page" type="integer">Echoes the requested page.</ResponseField>
    <ResponseField name="limit" type="integer">Page size that was applied.</ResponseField>
    <ResponseField name="total" type="integer">Total active records matching the query.</ResponseField>
    <ResponseField name="totalPages" type="integer">`Math.ceil(total / limit)`.</ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl 'https://www.wiseyield.co/api/v1/farms?page=1&limit=20&status=active&sort=name&order=asc' \
    -H "Authorization: Bearer $WISEYIELD_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    'https://www.wiseyield.co/api/v1/farms?page=1&limit=20&status=active&sort=name&order=asc',
    { headers: { Authorization: `Bearer ${process.env.WISEYIELD_API_KEY}` } }
  );
  const { data, pagination } = await res.json();
  console.log(`Got ${data.length} of ${pagination.total} farms`);
  ```

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

  res = requests.get(
      'https://www.wiseyield.co/api/v1/farms',
      params={'page': 1, 'limit': 20, 'status': 'active', 'sort': 'name', 'order': 'asc'},
      headers={'Authorization': f"Bearer {os.environ['WISEYIELD_API_KEY']}"},
  )
  body = res.json()
  print(f"Got {len(body['data'])} of {body['pagination']['total']} farms")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": [
      {
        "id": "11111111-2222-3333-4444-555555555555",
        "name": "Green Valley Farm",
        "farmType": "commercial",
        "primaryUse": "crops",
        "city": "Cairo",
        "country": "Egypt",
        "totalArea": "250",
        "areaUnit": "hectare",
        "soilType": "sandy loam",
        "irrigationSystem": "drip",
        "status": "active",
        "createdAt": "2026-04-12T10:00:00.000Z",
        "updatedAt": "2026-05-14T14:30:00.000Z"
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 20,
      "total": 1,
      "totalPages": 1
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": "Unauthorized",
    "message": "Invalid or revoked API key",
    "code": "INVALID_API_KEY"
  }
  ```

  ```json 403 Forbidden theme={null}
  {
    "error": "Forbidden",
    "message": "Insufficient permissions. Required scope: farms:read",
    "code": "INSUFFICIENT_SCOPE",
    "details": {
      "requiredScope": "farms:read",
      "availableScopes": ["crops:read"]
    }
  }
  ```

  ```json 429 Too Many Requests theme={null}
  {
    "error": "Rate limit exceeded",
    "code": "RATE_LIMIT_EXCEEDED"
  }
  ```
</ResponseExample>

***

## Create farm

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

### Authentication

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

### Request body

<ParamField body="name" type="string" required>
  1–200 characters.
</ParamField>

<ParamField body="city" type="string" required>
  1–200 characters.
</ParamField>

<ParamField body="country" type="string" required>
  1–200 characters.
</ParamField>

<ParamField body="totalArea" type="number" required>
  Positive number.
</ParamField>

<ParamField body="areaUnit" type="string" default="hectare">
  One of `hectare`, `acre`, `feddan`.
</ParamField>

<ParamField body="farmType" type="string">
  One of `commercial`, `organic`, `mixed`, `specialty`.
</ParamField>

<ParamField body="primaryUse" type="string">
  One of `crops`, `livestock`, `mixed`, `research`.
</ParamField>

<ParamField body="soilType" type="string">
  Up to 200 characters.
</ParamField>

<ParamField body="irrigationSystem" type="string">
  One of `drip`, `sprinkler`, `flood`, `pivot`, `manual`, `none`.
</ParamField>

<ParamField body="latitude" type="number">
  Between −90 and 90.
</ParamField>

<ParamField body="longitude" type="number">
  Between −180 and 180.
</ParamField>

<ParamField body="boundaries" type="object">
  GeoJSON `Polygon` (`{ type: "Polygon", coordinates: number[][][] }`).
</ParamField>

<ParamField body="status" type="string" default="active">
  One of `active`, `inactive`, `archived`, `draft`.
</ParamField>

### Response

Returns the created farm wrapped under `data`.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://www.wiseyield.co/api/v1/farms \
    -H "Authorization: Bearer $WISEYIELD_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Maple Ridge Farm",
      "city": "Portland",
      "country": "United States",
      "totalArea": 180,
      "areaUnit": "acre",
      "farmType": "organic",
      "primaryUse": "crops",
      "soilType": "loam",
      "irrigationSystem": "drip",
      "latitude": 45.5152,
      "longitude": -122.6784,
      "status": "active"
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch('https://www.wiseyield.co/api/v1/farms', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.WISEYIELD_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'Maple Ridge Farm',
      city: 'Portland',
      country: 'United States',
      totalArea: 180,
      areaUnit: 'acre',
      farmType: 'organic',
      primaryUse: 'crops',
      soilType: 'loam',
      irrigationSystem: 'drip',
      latitude: 45.5152,
      longitude: -122.6784,
      status: 'active',
    }),
  });

  const { data: farm } = await res.json();
  console.log('Created farm:', farm.id);
  ```

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

  res = requests.post(
      'https://www.wiseyield.co/api/v1/farms',
      headers={
          'Authorization': f"Bearer {os.environ['WISEYIELD_API_KEY']}",
          'Content-Type': 'application/json',
      },
      json={
          'name': 'Maple Ridge Farm',
          'city': 'Portland',
          'country': 'United States',
          'totalArea': 180,
          'areaUnit': 'acre',
          'farmType': 'organic',
          'primaryUse': 'crops',
          'soilType': 'loam',
          'irrigationSystem': 'drip',
          'latitude': 45.5152,
          'longitude': -122.6784,
          'status': 'active',
      },
  )
  farm = res.json()['data']
  print('Created farm:', farm['id'])
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "data": {
      "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "ownerId": "user_...",
      "name": "Maple Ridge Farm",
      "farmType": "organic",
      "primaryUse": "crops",
      "city": "Portland",
      "country": "United States",
      "totalArea": "180",
      "areaUnit": "acre",
      "soilType": "loam",
      "irrigationSystem": "drip",
      "latitude": "45.5152",
      "longitude": "-122.6784",
      "status": "active",
      "createdAt": "2026-05-17T14:23:01.000Z",
      "updatedAt": "2026-05-17T14:23:01.000Z"
    }
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "error": "Validation failed",
    "details": {
      "totalArea": ["Total area must be greater than 0"],
      "country": ["Country is required"]
    }
  }
  ```

  ```json 409 Conflict theme={null}
  {
    "error": "Conflict",
    "message": "A farm with this name already exists"
  }
  ```
</ResponseExample>

## Errors

| Status | When                                                                |
| ------ | ------------------------------------------------------------------- |
| `400`  | Validation failed — `details` carries per-field messages            |
| `401`  | Missing, malformed, expired, or revoked API key                     |
| `403`  | Key lacks `farms:read` (GET) or `farms:write` (POST)                |
| `409`  | Farm name already exists for this user (active rows only)           |
| `429`  | Rate limit reached — see [Rate-limit handling](/guides/rate-limits) |
| `5xx`  | Server error — retry with backoff                                   |

## Related

<CardGroup cols={2}>
  <Card title="Authentication" href="/authentication">
    Scopes, key format, rate limits
  </Card>

  <Card title="Pagination" href="/guides/pagination">
    Iterator patterns for list endpoints
  </Card>

  <Card title="Errors" href="/concepts/errors">
    Canonical error response shape
  </Card>

  <Card title="API Keys" href="/api-reference/api-keys/list-api-keys">
    Manage keys from your dashboard
  </Card>
</CardGroup>
