Base URL: https://tenders.ramram.in/api
Version: 1.0 MVP | Last Updated: December 2025
Authorization header.
Description: Authenticate user and receive JWT token
Request Body:
{
"email": "[email protected]",
"password": "admin123"
}
Response (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"email": "[email protected]",
"name": "Admin User",
"role": "admin"
}
}
Errors:
400 - Missing email or password401 - Invalid credentialsDescription: Logout (client-side token removal)
Response (200 OK):
{
"message": "Logged out successfully"
}
Description: List all tenders with optional filtering
Headers: Authorization: Bearer {token}
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| state | string | Filter by state (e.g., "Assam") |
| status | string | Filter by status (open, technical, financial, awarded) |
| search | string | Search in tender_no and title (case-insensitive) |
| limit | number | Results per page (default: 50) |
| offset | number | Pagination offset (default: 0) |
Response (200 OK):
{
"tenders": [
{
"id": 1,
"tender_no": "TEST_2025_001",
"title": "Road Construction Project",
"authority": "PWD Assam",
"state": "Assam",
"district": "Kamrup",
"closing_date": "2025-02-15T00:00:00.000Z",
"status": "open",
"created_at": "2025-12-30T04:56:03.627Z"
}
],
"limit": 50,
"offset": 0
}
Description: Create a new tender
Headers: Authorization: Bearer {token}
Request Body:
{
"tender_no": "MMPPNA_23_24_236",
"title": "Construction of RCC Culverts",
"authority": "PWD Assam",
"state": "Assam",
"district": "Cachar",
"closing_date": "2025-01-31",
"estimated_value": 5000000,
"status": "open",
"source_url": "https://..."
}
Response (201 Created):
{
"id": 2,
"tender_no": "MMPPNA_23_24_236",
"title": "Construction of RCC Culverts",
...
"created_at": "2025-12-30T05:00:00.000Z"
}
Errors:
400 - Invalid tender number409 - Tender number already existsDescription: Get single tender by ID
Headers: Authorization: Bearer {token}
Response (200 OK): Tender object
Errors: 404 - Tender not found
Description: Update tender (partial update supported)
Headers: Authorization: Bearer {token}
Request Body: Any tender fields to update
{
"status": "awarded",
"closing_date": "2025-02-28"
}
Response (200 OK): Updated tender object
Description: Upload BOQ file (ZIP/Excel) for processing
Headers: Authorization: Bearer {token}
Content-Type: multipart/form-data
Form Data:
file - File to upload (.zip, .xlsx, .xls)Constraints:
Response (201 Created):
{
"id": 1,
"tender_id": 1,
"file_type": "zip",
"original_filename": "work_59027.zip",
"storage_path": "/opt/claude/tenders/data/uploads/tender_1/...",
"file_size": 125669,
"checksum": "9b05547942dbd15208c1b34819e2c3049aa400494674a25c587516feb6976a65",
"uploaded_at": "2025-12-30T04:56:40.728Z"
}
Background Processing:
Errors:
400 - No file provided or invalid file type404 - Tender not found409 - Duplicate file (same checksum)413 - File too largeDescription: List uploaded files for a tender
Headers: Authorization: Bearer {token}
Response (200 OK):
{
"files": [
{
"id": 1,
"file_type": "zip",
"original_filename": "work_59027.zip",
"file_size": 125669,
"uploaded_at": "2025-12-30T04:56:40.728Z"
}
]
}
Description: Get BOQ rows for a tender
Headers: Authorization: Bearer {token}
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| pipe_only | boolean | Filter to show only RCC pipe items (true/false) |
| unmapped_only | boolean | Show only unmapped items (true/false) |
| limit | number | Results per page (default: 100) |
| offset | number | Pagination offset (default: 0) |
Response (200 OK):
{
"rows": [
{
"id": 292,
"tender_id": 1,
"file_id": 1,
"sheet_name": "BoQ1",
"row_number": 35,
"description_text": "Providing RCC pipe NP3 1000mm dia...",
"quantity": "22.5000",
"unit": "Rm",
"is_pipe_candidate": true,
"detected_attributes": {
"diameter_mm": 1000,
"class": "NP3",
"joint_type": "Collar Joint",
"bedding_type": "Granular"
},
"is_mapped": false,
"created_at": "2025-12-30T05:14:39.356Z"
}
],
"total": 4,
"limit": 100,
"offset": 0
}
Detected Attributes:
| Field | Type | Description |
|---|---|---|
| diameter_mm | number | Pipe diameter in millimeters |
| class | string | Pipe class (NP2, NP3, NP4, P1, P2, P3) |
| joint_type | string | Joint type (Flush Joint, Collar Joint, Spigot-Socket) |
| bedding_type | string | Bedding material (Granular, Concrete) |
Description: Get single BOQ row by ID
Headers: Authorization: Bearer {token}
Response (200 OK): BOQ row object with full details
Errors: 404 - Row not found
{
"error": "Error message description"
}
| Code | Meaning | Common Causes |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Invalid request data, validation failed |
| 401 | Unauthorized | Missing or invalid authentication token |
| 403 | Forbidden | Token expired, insufficient permissions |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate resource (tender number, file checksum) |
| 413 | Payload Too Large | File exceeds 50MB limit |
| 500 | Internal Server Error | Server-side error, check logs |
// Login
const loginResponse = await fetch('https://tenders.ramram.in/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: '[email protected]',
password: 'admin123'
})
});
const { token } = await loginResponse.json();
// Get tenders
const tendersResponse = await fetch('https://tenders.ramram.in/api/tenders', {
headers: { 'Authorization': `Bearer ${token}` }
});
const { tenders } = await tendersResponse.json();
// Upload file
const formData = new FormData();
formData.append('file', fileInput.files[0]);
const uploadResponse = await fetch('https://tenders.ramram.in/api/tenders/1/upload', {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: formData
});
const fileData = await uploadResponse.json();
# Login
curl -X POST https://tenders.ramram.in/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"admin123"}'
# Get pipe-only BOQ rows
curl "https://tenders.ramram.in/api/tenders/1/boq?pipe_only=true" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"
# Upload file
curl -X POST https://tenders.ramram.in/api/tenders/1/upload \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-F "file=@work_59027.zip"
API Documentation v1.0 | Tender Management System | © 2025