API contracts / App Service v2 / Endorsements

Why an endorsement action is allowed or blocked

OperationgetEndorsementEligibility
Call
GET /gateway/urvi-app-service/api/v2/endorsements/{entityType}/{entityId}/eligibility
Group
Endorsements
Features
Farmer endorsement details, VO / SHG / Farmer endorsement
Replaces today

Use case. Called online when the user opens the endorse action, so the UI can explain why Endorse is blocked and list the farmers or SHGs to fix. It evaluates exactly the rules the batch applies to endorsement_action; offline the app shows its local preview and the batch remains authoritative.

Rules.

  • Farmer: needs an IE id (ENDORSEMENT_FARMER_NOT_REGISTERED) and a frozen category (ENDORSEMENT_CATEGORY_NOT_FROZEN); C4 is endorsed directly; others need KAP submitted (ENDORSEMENT_KAP_NOT_SUBMITTED).
  • SHG: every active farmer registered and frozen; all-C4 SHGs endorse directly; otherwise every Farmer/C5 member needs KAP submitted.
  • VO: every SHG must already be endorsed (ENDORSEMENT_ORDER).
  • Transition not allowed from the current status -> ENDORSEMENT_TRANSITION_INVALID.

Error codes. ENDORSEMENT_ORDER, ENDORSEMENT_KAP_NOT_SUBMITTED, ENDORSEMENT_CATEGORY_NOT_FROZEN, ENDORSEMENT_FARMER_NOT_REGISTERED, ENDORSEMENT_TRANSITION_INVALID

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
entityTypepathEndorsementEntityTypeYesEndorsed entity type. · one of VO, SHG, FARMERSHG
entityIdpathinteger (int64)YesServer id of the VO, SHG or farmer.52001
actionqueryEndorsementActionTypeNoAction to evaluate. · one of ENDORSE, FLAG, NOT_RESOLVED, MARK_RESOLVED, UPLOAD_ABSTRACTENDORSE

Request

No body.

Responses

200 Eligibility.

Schema EndorsementEligibility.

Example 200 body
{
  "entityType": "SHG",
  "entityId": 52001,
  "action": "ENDORSE",
  "eligible": false,
  "evaluatedAt": "2025-10-14T09:30:00+05:30",
  "blockers": [
    {
      "code": "ENDORSEMENT_KAP_NOT_SUBMITTED",
      "message": "These members have not submitted KAP.",
      "farmers": [
        {
          "id": 700002,
          "clientId": "3f6c1a2e-0000-4000-8000-000000061442",
          "ieId": "IE-AP-0000002",
          "name": "Farmer B"
        }
      ]
    }
  ]
}
FieldTypeRequiredRulesMeaning
entityTypeEndorsementEntityTypeYesone of VO, SHG, FARMER
entityIdinteger (int64)YesServer id (assigned by the App Service).
actionEndorsementActionTypeYesone of ENDORSE, FLAG, NOT_RESOLVED, MARK_RESOLVED, UPLOAD_ABSTRACT
eligiblebooleanYes
blockersEligibilityBlocker[]Yes
evaluatedAtstring (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"
}