Accountability Chain API
The Accountability Chain maps every civic issue to its chain of responsible officials β from Ward Officer through Corporator, MLA, and MP. The system resolves an issue's location (pincode or coordinates) to the appropriate jurisdiction and returns the full hierarchy of accountable officials.
Entity Typesβ
| Entity Type | Description |
|---|---|
jurisdiction | A ward or area with pincode ranges, constituency codes, and references to its officials |
official | An elected or appointed official (Ward Officer, Corporator, MLA, MP) with contact info |
department | A municipal department responsible for a category of issues (roads, water, etc.) |
police_station | A police station with jurisdiction over specific pincodes |
Public Endpointsβ
GET /api/accountability-chainβ
Resolve the full accountability chain for a given location. Returns the jurisdiction, all officials in the hierarchy, relevant department, and police station.
Authentication: None required
Query parameters:
| Param | Type | Required | Description |
|---|---|---|---|
pincode | string | One of pincode or lat+lng | 6-digit Indian pincode |
lat | number | One of pincode or lat+lng | Latitude (used with lng for reverse geocoding) |
lng | number | One of pincode or lat+lng | Longitude (used with lat for reverse geocoding) |
category | string | β | Issue category β when provided, includes the relevant department in the response |
Response 200:
{
"success": true,
"data": {
"jurisdiction": {
"id": "mum-ward-a",
"city": "Mumbai",
"ward": "A",
"pincodes": ["400001", "400002"],
"constituency_assembly": "mah-assembly-colaba",
"constituency_parliamentary": "mah-parl-south-mumbai"
},
"officials": {
"ward_officer": {
"id": "off-mum-wo-a",
"name": "Ramesh Patil",
"designation": "Ward Officer",
"phone": "+919876543210",
"email": "ramesh.patil@mcgm.gov.in",
"whatsapp": "+919876543210",
"x_handle": "rameshpatil_wo"
},
"corporator": {
"id": "off-mum-corp-a",
"name": "Sunita Deshmukh",
"designation": "Corporator",
"phone": "+919876543211",
"email": "sunita.deshmukh@mcgm.gov.in"
},
"mla": {
"id": "off-mah-mla-colaba",
"name": "Anil Parab",
"designation": "MLA",
"constituency": "Colaba"
},
"mp": {
"id": "off-mah-mp-south-mumbai",
"name": "Arvind Sawant",
"designation": "MP",
"constituency": "South Mumbai"
}
},
"department": {
"id": "dept-mum-roads",
"name": "Roads & Bridges Department",
"city": "Mumbai",
"categories": ["road", "infrastructure"],
"contact_phone": "+912222620500"
},
"police_station": {
"id": "ps-mum-colaba",
"name": "Colaba Police Station",
"city": "Mumbai",
"pincodes": ["400001", "400005"],
"contact_phone": "+912222151613"
}
}
}
Response 404: No jurisdiction found for the given pincode/location.
Response 400: Missing required parameters (neither pincode nor lat+lng provided).
GET /api/jurisdictionsβ
List all jurisdictions, optionally filtered by city.
Authentication: None required
Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
city | string | β | Filter by city name (case-insensitive) |
limit | integer | 50 | 1β100 results per page |
lastKey | string | β | Pagination cursor |
Response 200:
{
"success": true,
"data": {
"count": 8,
"items": [
{
"id": "mum-ward-a",
"entityType": "jurisdiction",
"city": "Mumbai",
"ward": "A",
"pincodes": ["400001", "400002"],
"ward_officer_id": "off-mum-wo-a",
"corporator_id": "off-mum-corp-a",
"constituency_assembly": "mah-assembly-colaba",
"constituency_parliamentary": "mah-parl-south-mumbai"
}
],
"nextKey": null
}
}
GET /api/officialsβ
List all officials, optionally filtered by city or designation.
Authentication: None required
Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
city | string | β | Filter by city |
designation | string | β | Filter by designation (Ward Officer, Corporator, MLA, MP) |
limit | integer | 50 | 1β100 results per page |
lastKey | string | β | Pagination cursor |
Response 200:
{
"success": true,
"data": {
"count": 24,
"items": [
{
"id": "off-mum-wo-a",
"entityType": "official",
"name": "Ramesh Patil",
"designation": "Ward Officer",
"city": "Mumbai",
"ward": "A",
"phone": "+919876543210",
"email": "ramesh.patil@mcgm.gov.in",
"whatsapp": "+919876543210",
"x_handle": "rameshpatil_wo"
}
],
"nextKey": null
}
}
GET /api/departmentsβ
List all departments, optionally filtered by city.
Authentication: None required
Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
city | string | β | Filter by city |
limit | integer | 50 | 1β100 results per page |
lastKey | string | β | Pagination cursor |
Response 200:
{
"success": true,
"data": {
"count": 6,
"items": [
{
"id": "dept-mum-roads",
"entityType": "department",
"name": "Roads & Bridges Department",
"city": "Mumbai",
"categories": ["road", "infrastructure"],
"contact_phone": "+912222620500",
"contact_email": "roads@mcgm.gov.in"
}
],
"nextKey": null
}
}
GET /api/police-stationsβ
List all police stations, optionally filtered by city.
Authentication: None required
Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
city | string | β | Filter by city |
limit | integer | 50 | 1β100 results per page |
lastKey | string | β | Pagination cursor |
Response 200:
{
"success": true,
"data": {
"count": 4,
"items": [
{
"id": "ps-mum-colaba",
"entityType": "police_station",
"name": "Colaba Police Station",
"city": "Mumbai",
"pincodes": ["400001", "400005"],
"contact_phone": "+912222151613",
"address": "Shahid Bhagat Singh Rd, Colaba, Mumbai 400001"
}
],
"nextKey": null
}
}
Admin CRUD Endpointsβ
All admin endpoints require admin or superadmin role. Regular users receive 403 Forbidden.
POST /api/admin/accountability/:entityTypeβ
Create a new entity of the given type.
Auth required: Yes β admin or superadmin
Path parameters:
| Param | Values |
|---|---|
entityType | jurisdictions | officials | departments | police-stations |
Request body: JSON object matching the entity schema (see entity examples above).
Response 201: The created entity.
PUT /api/admin/accountability/:entityType/:idβ
Update an existing entity.
Auth required: Yes β admin or superadmin
Request body: JSON object with fields to update.
Response 200: The updated entity.
Response 404: Entity not found.
DELETE /api/admin/accountability/:entityType/:idβ
Delete an entity.
Auth required: Yes β admin or superadmin
Response 200: { "success": true }
Response 404: Entity not found.
GET /api/admin/accountability/:entityType/exportβ
Export all entities of the given type as CSV.
Auth required: Yes β admin or superadmin
Response: Content-Type: text/csv with all records for the entity type.
POST /api/admin/accountability/:entityType/importβ
Bulk import entities from CSV.
Auth required: Yes β admin or superadmin
Request body: Content-Type: multipart/form-data with a file field containing the CSV.
Response 200:
{
"success": true,
"data": {
"imported": 14,
"skipped": 0,
"errors": []
}
}
GET /api/admin/accountability/:entityTypeβ
List all entities of the given type (admin view with additional metadata).
Auth required: Yes β admin or superadmin
Response 200: Same shape as the public list endpoints, with additional createdAt/updatedAt fields.
GET /api/admin/accountability/:entityType/:idβ
Get a single entity by ID (admin view).
Auth required: Yes β admin or superadmin
Response 200: The full entity record.
Response 404: Entity not found.
Reverse Geocodingβ
When an issue is created with lat/lng coordinates but no pincode, the backend calls the OpenStreetMap Nominatim API to resolve the address:
GET https://nominatim.openstreetmap.org/reverse?lat={lat}&lon={lng}&format=json&addressdetails=1
The response is parsed to extract:
pincodefromaddress.postcodeareafromaddress.suburboraddress.neighbourhoodwardresolved by matching pincode against jurisdiction records
This geocoded data is stored on the issue record and used to resolve the accountability chain.
Rate limiting: Nominatim requests are rate-limited to 1 request per second per the API usage policy. The backend caches geocoding results for duplicate coordinates.