Session bootstrap after login and on cold start
Operation
getBootstrap- Call
GET /gateway/urvi-app-service/api/v2/session/bootstrap- Group
- Auth & session
- Features
- App startup and role detection, Village, Habitation and VO selection, Device registration and remote actions, Home and bottom bar, Side menu
- Replaces today
Use case. Called once right after login and on every cold start (cached; offline the app uses the last copy). Returns the user, tenant, flow type (Cadre / Unit / FCCC), typed permissions, the work-node tree for the Village > Habitation > VO picker, the device-binding status, pending remote actions, app-version policy and the current config ETag. The app routes: Cadre without a saved VO -> work-node selection; Unit -> unit data download; binding CONFLICT -> the non-dismissable device-conflict dialog; pending actions -> the remote-action lock screen.
Rules.
- Unit flow when any role contains
unit-inchargeorfmt_l1(tenantap.gov). - Device binding: no session -> the server registers this device (
BOUND_HERE); other device bound ->CONFLICTwithotherDevice. - No assigned work nodes -> 200 with an empty
workNodesarray; the app shows its "technical issue" error and offers logout.
Error codes. DEVICE_BLOCKED, VERSION_TOO_OLD
Parameters
| Name | In | Type | Required | Meaning | Example |
|---|---|---|---|---|---|
X-App-Version | header | string | Yes | App version `major.minor.patch+build`. Too old -> 426 `VERSION_TOO_OLD`. · pattern ^\d+\.\d+\.\d+(\+\d+)?$ | 2.0.0+200 |
X-Device-Id | header | string (uuid) | Yes | App-scoped device UUID (not ANDROID_ID). | 6b1f2c3d-0000-4000-8000-00000000d001 |
X-Request-Id | header | string (uuid) | No | Client-generated request id for tracing; echoed in responses and problems. | 0e0c5a1b-0000-4000-8000-0000000000a1 |
Accept-Language | header | string | No | Language for messages and labels. · one of en, te, ta; default "en" | te |
X-Tenant | header | string | No | Tenant code; must match the token. Urvi: `ap.gov`. · one of ap.gov | ap.gov |
Request
No body.
Responses
200 Bootstrap.
Schema Bootstrap.
{
"user": {
"userId": 9001,
"login": "user.a@@ap.gov",
"displayName": "User A",
"roleCodes": [
"role.ap.gov.cadre"
],
"flowType": "CADRE",
"permissions": {
"farmerAddEdit": true,
"readOnlyProfile": false,
"endorse": false,
"resolveFlags": true,
"compactBlocks": false,
"fmtCropEdit": false,
"voGeoFilter": false,
"analytics": true,
"surveys": false
},
"unitIncharge": {
"userId": 9002,
"displayName": "User B",
"roleCode": "role.ap.gov.unit-incharge"
}
},
"tenant": {
"code": "ap.gov",
"name": "RySS",
"languages": [
"en",
"te"
],
"timeZone": "Asia/Kolkata"
},
"workNodes": [
{
"id": 3101,
"code": "VIL-3101",
"type": "VILLAGE",
"name": {
"en": "Village A",
"te": "Village A (te)"
},
"parentId": null,
"children": [
{
"id": 3901,
"code": "HAB-3901",
"type": "HABITATION",
"name": {
"en": "Habitation A",
"te": "Habitation A (te)"
},
"parentId": 3101,
"children": [
{
"id": 4101,
"code": "VO-4101",
"type": "VO",
"name": {
"en": "VO A",
"te": "VO A (te)"
},
"parentId": 3901,
"children": []
}
]
}
]
}
],
"device": {
"enforced": true,
"status": "BOUND_HERE",
"canTakeOver": true
},
"pendingActions": [],
"appVersion": {
"minimum": "2.0.0",
"recommended": "2.1.0",
"latest": "2.1.0"
},
"configEtag": "\"cfg-2025-26-v41\"",
"serverTime": "2025-10-14T09:30:00+05:30",
"currentSeason": "2025-26"
}| Field | Type | Required | Rules | Meaning |
|---|---|---|---|---|
user | User | Yes | ||
tenant | Tenant | Yes | ||
workNodes | GeoNode[] | Yes | Work-node tree assigned to the user (districts down to SHGs for Cadre; VOs for Unit). | |
device | DeviceBindingStatus | Yes | ||
pendingActions | RemoteAction[] | No | ||
appVersion | AppVersionPolicy | Yes | ||
configEtag | string | Yes | Current ETag of `GET /config`; skip the config call when unchanged. | |
serverTime | string (date-time) | Yes | Use to detect a wrong device clock. | |
currentSeason | string | No | pattern ^\d{4}-\d{2}$ | Season label, e.g. `2025-26`. |
400 Malformed request or schema violation.
Schema Problem.
{
"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.
{
"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.
{
"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.
{
"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.
{
"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.
{
"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"
}