PORTING API Documentation
Complete guide to the PORTING REST API
Overview
The PORTING API provides comprehensive access to fleet tracking data, vehicle information, driver statistics, and real-time alerts. The API uses REST principles with JSON request/response format and requires API key authentication.
https://api.portingfour.co.ke/api/
Key Features
- Real-time Tracking: Get current vehicle locations and status
- Historical Data: Access detailed tracking history with date filtering
- Fleet Analytics: Generate reports on fuel efficiency, idle time, and more
- Alert Management: Monitor speeding, offline vehicles, and geofence violations
- Pagination Support: Efficiently handle large datasets
Error Handling
The API returns standard HTTP status codes. Error responses include a JSON body with details:
{
"success": false,
"error": {
"code": "INVALID_PARAMS",
"message": "Limit must be > 0 and offset must be >= 0"
}
}
Common Status Codes
| Code | Meaning | Resolution |
|---|---|---|
200 OK |
Request successful | No action needed |
400 Bad Request |
Invalid parameters or format | Check request parameters and format |
401 Unauthorized |
Missing or invalid API key | Include valid X-API-Key header |
403 Forbidden |
API key lacks permission | Use key with appropriate role |
404 Not Found |
Resource doesn't exist | Verify resource ID |
429 Too Many Requests |
Rate limit exceeded | Wait before making more requests |
500 Internal Server Error |
Server error | Retry later or contact support |
Error Codes
| Code | Description |
|---|---|
INVALID_PARAMS |
Request parameters are invalid |
NOT_FOUND |
Resource not found |
UNAUTHORIZED |
Authentication failed |
FORBIDDEN |
Access denied |
INTERNAL_ERROR |
Server error occurred |
Vehicles Endpoints
Manage and retrieve vehicle information, locations, and tracking data.
/api/vehicles
List All Vehicles
Get a paginated list of all vehicles with current status and location info
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit |
number | No | Results per page (default: 20, max: 100) |
offset |
number | No | Results to skip (default: 0) |
status |
string | No | Filter by status: active, idle, offline |
branch_id |
number | No | Filter by branch ID |
search |
string | No | Search by plate number or vehicle name |
Example Request
GET /api/vehicles?limit=10&status=active
Authorization: Bearer sk_live_xxx
Example Response
{
"success": true,
"data": {
"vehicles": [
{
"id": 1,
"plate_number": "ABC-1234",
"name": "Delivery Van 1",
"status": "active",
"current_location": {
"latitude": 40.7128,
"longitude": -74.0060,
"location_name": "New York, NY"
},
"branch_id": 1,
"branch_name": "NYC Branch",
"speed": 45,
"last_update": "2026-02-05T10:30:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
],
"total": 150,
"limit": 10,
"offset": 0
}
}
/api/vehicles/:id
Get Vehicle Details
Get detailed information about a specific vehicle including location and stats
Parameters
| Name | Type | Location | Description |
|---|---|---|---|
id |
number | URL Path | Vehicle ID (required) |
Example Request
GET /api/vehicles/1
Authorization: Bearer sk_live_xxx
Example Response
{
"success": true,
"data": {
"id": 1,
"plate_number": "ABC-1234",
"name": "Delivery Van 1",
"status": "active",
"current_location": {
"latitude": 40.7128,
"longitude": -74.0060,
"location_name": "New York, NY"
},
"speed": 45,
"branch_id": 1,
"branch_name": "NYC Branch",
"total_distance": 5432,
"last_update": "2026-02-05T10:30:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
}
/api/vehicles/:id/location
Get Current Location
Get only the current location of a vehicle (lightweight, fast endpoint - useful for live maps)
Example Request
GET /api/vehicles/1/location
Authorization: Bearer sk_live_xxx
Example Response
{
"success": true,
"data": {
"vehicle_id": 1,
"latitude": 40.7128,
"longitude": -74.0060,
"location_name": "New York, NY",
"speed": 45,
"timestamp": "2026-02-05T10:30:00Z",
"accuracy": 5
}
}
/api/vehicles/:id/history
Get Tracking History
Get historical tracking records for a vehicle with date filtering and pagination
Parameters
| Name | Type | Description |
|---|---|---|
id |
number | Vehicle ID (required, in URL) |
date_from |
string (ISO 8601) | Start date (default: 7 days ago) |
date_to |
string (ISO 8601) | End date (default: now) |
status |
string | Filter by status: active, idle, offline |
limit |
number | Results per page (default: 100, max: 500) |
offset |
number | Results to skip (default: 0) |
Example Request
GET /api/vehicles/1/history?date_from=2026-02-01T00:00:00Z&date_to=2026-02-05T23:59:59Z&limit=50
Authorization: Bearer sk_live_xxx
Example Response
{
"success": true,
"data": {
"vehicle_id": 1,
"plate_number": "ABC-1234",
"date_from": "2026-02-01T00:00:00Z",
"date_to": "2026-02-05T23:59:59Z",
"records": [
{
"id": 1001,
"timestamp": "2026-02-05T10:30:00Z",
"latitude": 40.7128,
"longitude": -74.0060,
"location_name": "New York, NY",
"speed": 45,
"status": "active",
"accuracy": 5,
"poi": "Times Square"
}
],
"total": 250,
"limit": 50,
"offset": 0
}
}
/api/vehicles/:id/geofence-alerts
Get Geofence Alerts
Get geofence entry/exit events for a vehicle
Parameters
| Name | Type | Description |
|---|---|---|
id |
number | Vehicle ID (required, in URL) |
limit |
number | Results per page (default: 50, max: 200) |
offset |
number | Results to skip (default: 0) |
Example Request
GET /api/vehicles/1/geofence-alerts?limit=20
Authorization: Bearer sk_live_xxx
Drivers Endpoints
Access driver information and vehicle assignments.
/api/drivers
List All Drivers
Get paginated list of all drivers with assignment statistics
Parameters
| Name | Type | Description |
|---|---|---|
limit |
number | Results per page (default: 20, max: 100) |
offset |
number | Results to skip (default: 0) |
Example Request
GET /api/drivers?limit=10&offset=0
Authorization: Bearer sk_live_xxx
/api/drivers/:id/assignments
Get Driver Assignments
Get vehicle assignments and tracking history for a specific driver
Example Request
GET /api/drivers/1/assignments?limit=10
Authorization: Bearer sk_live_xxx
Branches Endpoints
Get branch information and fleet statistics.
/api/branches
List All Branches
Get paginated list of all branches with vehicle count summaries
Parameters
| Name | Type | Description |
|---|---|---|
limit |
number | Results per page (default: 20, max: 100) |
offset |
number | Results to skip (default: 0) |
Example Request
GET /api/branches?limit=10
Authorization: Bearer sk_live_xxx
/api/branches/:id/summary
Get Branch Summary
Get detailed branch statistics including all vehicles and operational metrics
Example Request
GET /api/branches/1/summary
Authorization: Bearer sk_live_xxx
Alerts Endpoints
Real-time alerts and event notifications from fleet operations.
/api/alerts
Get Recent Alerts
Get recent alerts detected from tracking data. Alert types include: SPEEDING, OFFLINE, GEOFENCE_BREACH, IDLE
Parameters
| Name | Type | Description |
|---|---|---|
alert_type |
string | Filter by type: SPEEDING, OFFLINE, GEOFENCE_BREACH, IDLE |
vehicle_id |
number | Filter by specific vehicle |
limit |
number | Results per page (default: 50, max: 200) |
offset |
number | Results to skip (default: 0) |
Alert Types
- SPEEDING: Vehicle speed exceeds threshold (default: 100 km/h)
- OFFLINE: Vehicle has no tracking for > 1 hour
- GEOFENCE_BREACH: Unauthorized geofence entry/exit
- IDLE: Vehicle stationary for > 30 minutes
Example Request
GET /api/alerts?alert_type=SPEEDING&limit=25
Authorization: Bearer sk_live_xxx
Example Response
{
"success": true,
"data": {
"alerts": [
{
"id": 1001,
"type": "SPEEDING",
"severity": "warning",
"vehicle_id": 1,
"plate_number": "ABC-1234",
"timestamp": "2026-02-05T10:30:00Z",
"message": "Vehicle ABC-1234 exceeding speed limit",
"value": 85,
"threshold": 100
}
],
"total": 342,
"limit": 25,
"offset": 0
}
}
Tracking Endpoints
Historical tracking data and route information.
GET /api/vehicles/:id/history and GET /api/vehicles/:id/geofence-alerts for detailed examples.
Reports Endpoints
Generate and retrieve fleet analytics reports.
/api/reports/idle-vehicles
Idle Vehicles Report
Get list of idle vehicles and idle time statistics
Parameters
| Name | Type | Description |
|---|---|---|
idle_minutes |
number | Consider idle if stationary for N minutes (default: 30) |
limit |
number | Results per page (default: 50, max: 200) |
offset |
number | Results to skip (default: 0) |
Example Request
GET /api/reports/idle-vehicles?idle_minutes=30&limit=25
Authorization: Bearer sk_live_xxx
/api/reports/fuel-efficiency
Fuel Efficiency Report
Get fuel efficiency metrics for vehicles across specified date range
Parameters
| Name | Type | Description |
|---|---|---|
vehicle_id |
number | Filter by specific vehicle (optional) |
date_from |
string (ISO 8601) | Start date |
date_to |
string (ISO 8601) | End date |
Example Request
GET /api/reports/fuel-efficiency?date_from=2026-02-01T00:00:00Z&date_to=2026-02-05T23:59:59Z
Authorization: Bearer sk_live_xxx
/api/reports/geofence-compliance
Geofence Compliance Report
Get geofence violation and compliance metrics
Parameters
| Name | Type | Description |
|---|---|---|
date_from |
string (ISO 8601) | Start date |
date_to |
string (ISO 8601) | End date |
Example Request
GET /api/reports/geofence-compliance
Authorization: Bearer sk_live_xxx
Rate Limiting
The API implements rate limiting based on your API key role. Rate limits are enforced per hour.
| Role | Requests/Hour | Response Header |
|---|---|---|
| guest | 100 | X-RateLimit-Limit: 100 |
| viewer | 1,000 | X-RateLimit-Limit: 1000 |
| operator | 5,000 | X-RateLimit-Limit: 5000 |
| admin | Unlimited | N/A |
Rate Limit Headers
Each response includes rate limit information:
X-RateLimit-Limit: 1000 # Your hourly limit
X-RateLimit-Remaining: 995 # Requests remaining
X-RateLimit-Reset: 1675420800 # Unix timestamp when limit resets
429 Too Many Requests response. Wait until the reset time before making more requests.
Best Practices
1. Use Appropriate Pagination
Always paginate large datasets. Use reasonable limit values (20-100) and iterate through results using offset.
// Good: Paginate through results
GET /api/vehicles?limit=50&offset=0
GET /api/vehicles?limit=50&offset=50
GET /api/vehicles?limit=50&offset=100
// Bad: Requesting too many results at once
GET /api/vehicles?limit=10000
2. Filter When Possible
Use query parameters to filter data server-side, reducing response size and improving performance.
// Good: Filter by status
GET /api/vehicles?status=active&limit=20
// Less efficient: Get all then filter client-side
GET /api/vehicles?limit=1000
3. Cache Responses
Cache responses locally to reduce API calls. Location data can be cached for 30-60 seconds, historical data for longer periods.
4. Handle Errors Gracefully
Always handle error responses and implement retry logic with exponential backoff for transient failures.
async function apiCall(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, { headers });
if (response.status === 429) {
// Rate limited: wait before retry
await sleep(1000 * Math.pow(2, i));
continue;
}
return response.json();
} catch (error) {
if (i === retries - 1) throw error;
await sleep(1000 * Math.pow(2, i));
}
}
}
Support & Troubleshooting
Common Issues
401 Unauthorized
Issue: API key is missing or invalid
Solution:
- Verify you're including the
Bearerheader - Check that the key is correct (copy-paste from dashboard)
- Ensure the key hasn't been revoked
- Generate a new key if needed
403 Forbidden
Issue: API key doesn't have permission for this endpoint
Solution:
- Check your API key's role in the dashboard
- Verify the endpoint requires your role level or higher
- Request a key with appropriate role
429 Too Many Requests
Issue: Rate limit exceeded
Solution:
- Check
X-RateLimit-Resetheader for reset time - Implement backoff logic in your client
- Consider upgrading to higher tier role for higher limits
- Optimize your requests to use less quota