API contracts / App Service v2 / Land & geofence

Owned, leased, used and available acres

OperationgetFarmerMetrics
Call
GET /gateway/urvi-app-service/api/v2/farmers/{farmerId}/metrics
Group
Land & geofence
Features
Land assets, Leased land, ATM model (Anytime Money plot), Crop Actual (portfolio), KAP / Annual Action Plan 2025-26
Replaces today

Use case. Called online by the Land edit, Leased land (for the lessor's parcels), ATM, Crop Actual and KAP screens to show available acres. Uses exactly the formula the batch validation applies: available = owned + leased-in - leased-out - current-season Crop Actual (unharvested, latest per tile) - latest ATM sizes. Offline the app computes the same figure locally.

Rules.

  • Values in acres, 2 decimals.

Error codes. NOT_FOUND

Parameters

NameInTypeRequiredMeaningExample
X-App-VersionheaderstringYesApp version `major.minor.patch+build`. Too old -> 426 `VERSION_TOO_OLD`. · pattern ^\d+\.\d+\.\d+(\+\d+)?$2.0.0+200
X-Device-Idheaderstring (uuid)YesApp-scoped device UUID (not ANDROID_ID).6b1f2c3d-0000-4000-8000-00000000d001
X-Request-Idheaderstring (uuid)NoClient-generated request id for tracing; echoed in responses and problems.0e0c5a1b-0000-4000-8000-0000000000a1
Accept-LanguageheaderstringNoLanguage for messages and labels. · one of en, te, ta; default "en"te
X-TenantheaderstringNoTenant code; must match the token. Urvi: `ap.gov`. · one of ap.govap.gov
farmerIdpathstringYesFarmer server id or client UUID (`aliasId`). With a UUID unknown to the server, the farmer is created from the flat master record (get-or-create). · min length 1; max length 643f6c1a2e-0000-4000-8000-00000000f001
seasonquerystringNo`current`, `previous` or an explicit season like `2025-26`; the server maps it to year-specific datasets. · pattern ^(current|previous|\d{4}-\d{2})$; default "current"current

Request

No body.

Responses

200 Metrics.

Schema FarmerMetrics.

Example 200 body
{
  "ownedAcres": 2.5,
  "leasedInAcres": 0,
  "leasedOutAcres": 0.75,
  "cropActualAcres": 1.5,
  "atmAcres": 0.25,
  "usedAcres": 2.5,
  "availableAcres": 0,
  "kapSurveyCount": 1,
  "computedAt": "2025-10-14T09:30:00+05:30",
  "parcels": [
    {
      "landId": 810001,
      "landClientId": "4a7d2b3f-0000-4000-8000-000000004097",
      "surveyNo": "SY-101/2",
      "totalAcres": 2.5,
      "leasedOutAcres": 0.75,
      "cropActualAcres": 1.5,
      "atmAcres": 0.25,
      "availableAcres": 0,
      "disabled": false
    }
  ]
}
FieldTypeRequiredRulesMeaning
ownedAcresnumber (double)Yes≥ 0Unit: acres.
leasedInAcresnumber (double)No≥ 0
leasedOutAcresnumber (double)No≥ 0
cropActualAcresnumber (double)No≥ 0Current-season, current-month Crop Actual acres (unharvested, latest per tile).
atmAcresnumber (double)No≥ 0Latest version of every ATM.
usedAcresnumber (double)No≥ 0
availableAcresnumber (double)Yes
kapSurveyCountintegerNo≥ 0
parcelsParcelAvailability[]Yes
computedAtstring (date-time)No

400 Malformed request or schema violation.

Schema Problem.

Example 400 body
{
  "type": "https://urvi.example.invalid/problems/validation-failed",
  "title": "Validation failed",
  "status": 400,
  "detail": "One or more fields are invalid.",
  "code": "VALIDATION_FAILED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1",
  "errors": [
    {
      "field": "/mobile",
      "code": "INVALID_MOBILE",
      "message": "Mobile must be 10 digits starting 6-9."
    }
  ]
}

401 Missing, invalid or expired access token. Refresh once, then ask the user to log in; pending outbox ops stay intact.

Schema Problem.

Example 401 body
{
  "type": "https://urvi.example.invalid/problems/token-expired",
  "title": "Session expired",
  "status": 401,
  "detail": "The access token has expired.",
  "code": "TOKEN_EXPIRED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}

403 Authenticated but not allowed (role, tenant, device binding or feature switch).

Schema Problem.

Example 403 body
{
  "type": "https://urvi.example.invalid/problems/role-not-allowed",
  "title": "Not allowed",
  "status": 403,
  "detail": "Your role cannot perform this action.",
  "code": "ROLE_NOT_ALLOWED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}

404 Resource not found or outside the user's work nodes.

Schema Problem.

Example 404 body
{
  "type": "https://urvi.example.invalid/problems/not-found",
  "title": "Not found",
  "status": 404,
  "detail": "No such resource in your work area.",
  "code": "NOT_FOUND",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}

426 App version below the minimum; block the UI with an update prompt. Pending outbox ops are kept.

Schema Problem.

Example 426 body
{
  "type": "https://urvi.example.invalid/problems/version-too-old",
  "title": "Update required",
  "status": 426,
  "detail": "Please update Urvi to continue.",
  "code": "VERSION_TOO_OLD",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1",
  "minAppVersion": "2.0.0"
}

429 Rate limited per device / user. Respect `Retry-After`.

Schema Problem.

Example 429 body
{
  "type": "https://urvi.example.invalid/problems/rate-limited",
  "title": "Too many requests",
  "status": 429,
  "detail": "Slow down and retry later.",
  "code": "RATE_LIMITED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1",
  "retryAfterSeconds": 30
}

500 Unexpected server error; retry with backoff (writes are idempotent).

Schema Problem.

Example 500 body
{
  "type": "https://urvi.example.invalid/problems/internal-error",
  "title": "Server error",
  "status": 500,
  "detail": "Something went wrong. Please try again.",
  "code": "INTERNAL_ERROR",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}