Overview
The Corporations of Greater Bengaluru API enables developers to integrate civic complaint management into their applications. Submit complaints, track status, and access municipal corporation data programmatically.
🌐 Base URL:
https://notf-cms.vercel.app/api
Key Features
- ✅ Submit complaints to 12 Indian cities
- ✅ Auto-route complaints to correct municipal corporation
- ✅ Support for base64 photo uploads and GPS location data
- ✅ Real-time ticket number generation
- ✅ Automatic issue categorization (304 categories)
- ✅ Category code to UUID auto-conversion
- ✅ No authentication required for public endpoints
Authentication
Currently, the API is publicly accessible with no authentication required. Future versions may include API keys for advanced features.
⚠️ Rate Limiting: While no API key is required, please be mindful of request volume. We reserve the right to implement rate limits in the future.
Endpoints
POST
/submit-complaint
Submit a new civic complaint to a municipal corporation.
Request Format
Required Headers
| Header | Value | Description |
|---|---|---|
| Content-Type | application/json |
Request body format |
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| description | string | Required | Detailed description of the issue (min 10 characters) |
| address | string | Required | Full address where the issue exists |
| citizen_phone | string | Required* | 10-digit Indian mobile number (starts with 6-9) |
| citizen_email | string | Required* | Valid email address |
| latitude | number | Optional | GPS latitude coordinate |
| longitude | number | Optional | GPS longitude coordinate |
| corporation_id | string | Optional | Corporation code (e.g., "chennai", "north") or UUID |
| category_id | string | Optional | Issue category code (e.g., "garbage_not_collected") or UUID |
| citizen_name | string | Optional | Name of complainant (can be anonymous) |
| photo | string | Optional | Base64-encoded image with data URL prefix (e.g., "data:image/jpeg;base64,...") |
| photo_filename | string | Optional | Original filename of the photo (used with photo parameter) |
| photo_size | number | Optional | File size in bytes (used with photo parameter) |
* Contact Requirement: At least one of
citizen_phone or citizen_email must be provided.
📸 Photo Upload: Photos must be sent as base64-encoded strings in JSON format. FormData/multipart requests are not supported. Use the FileReader API to convert images to base64 before sending.
Supported Cities
Use these corporation codes for the corporation_id parameter:
| Code | City | State |
|---|---|---|
bengaluru or north/south/east/west/central | Bengaluru | Karnataka |
ahmedabad | Ahmedabad | Gujarat |
bhubaneswar | Bhubaneswar | Odisha |
chennai | Chennai | Tamil Nadu |
gurugram | Gurugram | Haryana |
hyderabad | Hyderabad | Telangana |
jaipur | Jaipur | Rajasthan |
kolkata | Kolkata | West Bengal |
mumbai | Mumbai | Maharashtra |
pune | Pune | Maharashtra |
thane | Thane | Maharashtra |
visakhapatnam | Visakhapatnam | Andhra Pradesh |
Example Request (Without Photo)
{
"description": "Streetlight not working on MG Road near City Center",
"address": "MG Road, Bengaluru North, Karnataka 560001",
"latitude": 12.9716,
"longitude": 77.5946,
"citizen_phone": "9876543210",
"citizen_name": "Ramesh Kumar",
"corporation_id": "north",
"category_id": "streetlight_not_working"
}
Example Request (With Photo)
{
"description": "Broken pavement causing safety hazard",
"address": "MG Road, Bengaluru North, Karnataka 560001",
"latitude": 12.9716,
"longitude": 77.5946,
"citizen_phone": "9876543210",
"citizen_name": "Ramesh Kumar",
"corporation_id": "north",
"category_id": "pavement_broken",
"photo": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
"photo_filename": "broken-pavement.jpg",
"photo_size": 245678
}
Response Format
Success Response (200 OK)
{
"success": true,
"complaint": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"complaint_number": "NOR-26-000123",
"corporation_id": "123e4567-e89b-12d3-a456-426614174000",
"category_id": "789e4567-e89b-12d3-a456-426614174000",
"description": "Streetlight not working on MG Road near City Center",
"address": "MG Road, Bengaluru North, Karnataka 560001",
"latitude": 12.9716,
"longitude": 77.5946,
"citizen_name": "Ramesh Kumar",
"citizen_phone": "9876543210",
"status": "new",
"created_at": "2026-01-18T12:30:45.123Z"
},
"complaint_number": "NOR-26-000123",
"id": "550e8400-e29b-41d4-a716-446655440000",
"photo_url": "https://abblyaukkoxmgzwretvm.supabase.co/storage/v1/object/public/notf-cms/550e8400-e29b-41d4-a716-446655440000/1737203445123.jpg",
"message": "Complaint submitted successfully. Ticket: NOR-26-000123"
}
📸 Photo URL: If a photo was uploaded, the
photo_url field contains the public URL to the uploaded image in Supabase Storage. This field is null if no photo was provided.
✅ Ticket Numbers: Format is
{CORP_CODE}-{YEAR}-{NUMBER}. Example: NOR-26-000123 (Bengaluru North, 2026, complaint #123)
Error Handling
Error Response Format
{
"error": "Description must be at least 10 characters long."
}
HTTP Status Codes
| Status Code | Meaning | Description |
|---|---|---|
200 |
OK | Complaint submitted successfully |
400 |
Bad Request | Invalid parameters or missing required fields |
405 |
Method Not Allowed | HTTP method not supported (use POST) |
500 |
Internal Server Error | Server-side error occurred |
Common Error Messages
"Description must be at least 10 characters long.""Please provide either a phone number or email address.""Invalid phone number. Must be 10 digits starting with 6-9.""Invalid email address format.""Invalid corporation code: {code}"
Code Examples
JavaScript (Fetch API)
// Without photo
const response = await fetch('https://notf-cms.vercel.app/api/submit-complaint', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: 'Streetlight not working on MG Road',
address: 'MG Road, Bengaluru North, Karnataka 560001',
latitude: 12.9716,
longitude: 77.5946,
citizen_phone: '9876543210',
citizen_name: 'Ramesh Kumar',
corporation_id: 'north',
category_id: 'streetlight_not_working'
})
});
const data = await response.json();
console.log('Ticket Number:', data.complaint_number);
// With photo upload
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
// Convert photo to base64
const photoFile = document.getElementById('photoInput').files[0];
const base64Photo = await fileToBase64(photoFile);
const responseWithPhoto = await fetch('https://notf-cms.vercel.app/api/submit-complaint', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: 'Broken pavement causing safety hazard',
address: 'MG Road, Bengaluru North, Karnataka 560001',
latitude: 12.9716,
longitude: 77.5946,
citizen_phone: '9876543210',
citizen_name: 'Ramesh Kumar',
corporation_id: 'north',
category_id: 'pavement_broken',
photo: base64Photo,
photo_filename: photoFile.name,
photo_size: photoFile.size
})
});
const dataWithPhoto = await responseWithPhoto.json();
console.log('Ticket Number:', dataWithPhoto.complaint_number);
console.log('Photo URL:', dataWithPhoto.photo_url);
Python (Requests)
import requests
import base64
# Without photo
response = requests.post(
'https://notf-cms.vercel.app/api/submit-complaint',
json={
'description': 'Streetlight not working on MG Road',
'address': 'MG Road, Bengaluru North, Karnataka 560001',
'latitude': 12.9716,
'longitude': 77.5946,
'citizen_phone': '9876543210',
'citizen_name': 'Ramesh Kumar',
'corporation_id': 'north',
'category_id': 'streetlight_not_working'
}
)
data = response.json()
print(f"Ticket Number: {data['complaint_number']}")
# With photo upload
with open('photo.jpg', 'rb') as photo_file:
photo_data = photo_file.read()
base64_photo = f"data:image/jpeg;base64,{base64.b64encode(photo_data).decode('utf-8')}"
response_with_photo = requests.post(
'https://notf-cms.vercel.app/api/submit-complaint',
json={
'description': 'Broken pavement causing safety hazard',
'address': 'MG Road, Bengaluru North, Karnataka 560001',
'latitude': 12.9716,
'longitude': 77.5946,
'citizen_phone': '9876543210',
'citizen_name': 'Ramesh Kumar',
'corporation_id': 'north',
'category_id': 'pavement_broken',
'photo': base64_photo,
'photo_filename': 'photo.jpg',
'photo_size': len(photo_data)
}
)
data_with_photo = response_with_photo.json()
print(f"Ticket Number: {data_with_photo['complaint_number']}")
print(f"Photo URL: {data_with_photo['photo_url']}")
cURL
curl -X POST https://notf-cms.vercel.app/api/submit-complaint \
-H "Content-Type: application/json" \
-d '{
"description": "Streetlight not working on MG Road",
"address": "MG Road, Bengaluru North, Karnataka 560001",
"latitude": 12.9716,
"longitude": 77.5946,
"citizen_phone": "9876543210",
"citizen_name": "Ramesh Kumar",
"corporation_id": "north",
"category_id": "streetlight_not_working"
}'
Try It Out
🧪 Test the API Live
Rate Limits
Currently, there are no strict rate limits. However, we recommend:
- Maximum 100 requests per minute from a single IP
- Implement exponential backoff for retries
- Cache responses when appropriate
⚠️ Fair Use Policy: Please use the API responsibly. Excessive usage may result in temporary IP blocking.
Support & Feedback
Need help? Found a bug? Have a feature request?
- 📧 Email: support@notf.in
- 💬 GitHub Issues: Report an issue
- 📖 Documentation: This page is regularly updated
📝 Changelog: Last updated January 18, 2026 - Added base64 photo upload support and category code auto-conversion (all 304 categories available)