API contracts / App Service v2 / Analytics

MIS dashboard for cadre or unit

OperationgetAnalyticsDashboard
Call
GET /gateway/urvi-app-service/api/v2/analytics/dashboard
Group
Analytics
Features
Analytics dashboard
Replaces today

Use case. Called online by the Analytics dashboard (on open when the cache is older than today, on Refresh, and every sync.analyticsRefreshHours for Cadre). Returns yesterday / month / overall counts, nine-principles adoption, VO / SHG / cadre breakdown, drill-down farmer ids and the filter options in one response. The app caches it for the day and stores the filter selection locally.

Rules.

  • scope=unit requires the Unit flow; scope=cadre returns only the caller's work area.

Error codes. ROLE_NOT_ALLOWED

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
scopequerystringYes`cadre` or `unit`. · one of cadre, unitunit
cadreIdsqueryinteger (int64)[]NoUnit only.9001
voIdsqueryinteger (int64)[]NoVO filter.4101
shgIdsqueryinteger (int64)[]NoSHG filter (Unit).52001

Request

No body.

Responses

200 Dashboard.

Schema AnalyticsDashboard.

Example 200 body
{
  "scope": "unit",
  "asOf": "2025-10-14T09:30:00+05:30",
  "yesterday": {
    "farmersSurveyed": 12,
    "c1Farmers": 8,
    "c1Acres": 14.5,
    "s2sFarmers": 3,
    "s2sAcres": 4.25
  },
  "month": {
    "farmersSurveyed": 140,
    "c1Farmers": 96,
    "c1Acres": 180.5,
    "s2sFarmers": 31,
    "s2sAcres": 52,
    "target": 300,
    "coveragePercent": 46.7
  },
  "overall": {
    "farmersSurveyed": 820,
    "c1Farmers": 610,
    "c1Acres": 1102.75,
    "s2sFarmers": 205,
    "s2sAcres": 330.5,
    "target": 1000,
    "coveragePercent": 82
  },
  "ninePrinciples": [
    {
      "code": "P1_SOIL_COVER",
      "label": {
        "en": "Soil always covered",
        "te": "Soil always covered (te)"
      },
      "farmers": 410,
      "percent": 50
    }
  ],
  "breakdown": [
    {
      "level": "VO",
      "id": "4101",
      "name": "VO A",
      "counts": {
        "farmersSurveyed": 220,
        "c1Farmers": 170
      }
    }
  ],
  "drilldowns": [
    {
      "metric": "c1Farmers",
      "period": "YESTERDAY",
      "farmerIds": [
        700001,
        700002
      ]
    }
  ],
  "filterOptions": {
    "cadres": [
      {
        "userId": 9001,
        "displayName": "User A"
      }
    ],
    "vos": [
      {
        "id": 4101,
        "type": "VO",
        "name": "VO A",
        "code": "VO-4101"
      }
    ],
    "shgs": [
      {
        "id": 52001,
        "type": "SHG",
        "name": "SHG A",
        "code": "SHG-52001"
      }
    ]
  }
}
FieldTypeRequiredRulesMeaning
scopestringYesone of cadre, unit
asOfstring (date-time)Yes
yesterdayAnalyticsCountsYes
monthAnalyticsCountsYes
overallAnalyticsCountsYes
ninePrinciplesPrincipleAdoption[]No
breakdownAnalyticsBreakdownRow[]No
drilldownsAnalyticsDrilldown[]No
filterOptionsobjectNo

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"
}

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"
}