Traccar Integration — Complete Guide
- What is Traccar & Why It's Here Traccar is an open-source GPS tracking server. In Motoshare, it is used to:
Register each vehicle's GPS device (identified by its IMEI number)
Track live vehicle position (latitude, longitude, speed, etc.)
Let partners open a live tracking map in the browser
- Architecture
Mobile/Web App
│
▼
Laravel API (motoshare-web)
│
├── TraccarService ──► Traccar Server HTTP API (port 8082)
│ /api/users
│ /api/devices
│ /api/positions
│ /api/session
│ /api/session/token
│
├── addvechicles table (stores imei + traccar_device_id)
└── users table (stores traccar_password)
Two key database columns added by migrations:
Table Column Purpose
addvechicles traccar_device_id Cached Traccar internal device ID (skips IMEI lookup on every position call)
users traccar_password Stored Traccar password for generating per-user JWT tokens
- Configuration (.env Variables) Add these to your .env file:
Traccar server URL — the backend API (Laravel calls this internally)
TRACCAR_API_URL=http://localhost:8082
Traccar admin credentials (must be a Traccar admin account)
TRACCAR_API_ADMIN_EMAIL=admin@example.com
TRACCAR_API_ADMIN_PASSWORD=your_admin_password
Traccar web UI URL (browser-facing, for the map redirect)
TRACCAR_WEB_URL=http://localhost:8082
HTTP timeout in seconds
TRACCAR_API_TIMEOUT=10
Set false on local dev if Traccar has a self-signed SSL cert
TRACCAR_VERIFY_SSL=true
Master switch — set true to enable the integration
TRACCAR_ENABLED=true
Important: TRACCAR_API_URL and TRACCAR_WEB_URL can be different. API URL is what Laravel connects to (may be internal network). Web URL is what the browser opens (must be publicly reachable).
- All API Endpoints 4.1 Get Traccar JWT Token
GET /api/traccar/token
Auth: Sanctum token required
What it does: Generates a JWT for the logged-in user so the frontend can open the Traccar map UI.
Response:
{ "traccar_token": "eyJhbGciOi..." }
Usage (frontend):
// Open Traccar map for logged-in user
const res = await axios.get('/api/traccar/token');
window.open(${TRACCAR_WEB_URL}?token=${res.data.traccar_token});
4.2 Get Live Vehicle Position
GET /api/vehicles/{vehicleId}/position
Auth: Sanctum token required
What it does: Returns the latest GPS position for a vehicle by its Motoshare vehicle ID.
Response:
{
"vehicle_id": 42,
"imei": "123456789012345",
"latitude": 12.9716,
"longitude": 77.5946,
"speed": 0.0,
"course": 180.0,
"accuracy": 5.2,
"altitude": 920.0,
"device_time": "2026-06-02T10:30:00.000+0000",
"fix_time": "2026-06-02T10:29:58.000+0000",
"attributes": { "ignition": true, "motion": false }
}
Error responses:
{ "error": "Vehicle not found or no GPS device" } // 404 — vehicle missing or no IMEI set
{ "error": "No position data available" } // 404 — device registered but no GPS fix yet
{ "error": "Internal server error" } // 500
4.3 Get Live Position by Booking
GET /api/bookings/{bookingId}/position
Auth: Sanctum token required
What it does: Same as above but looks up the vehicle through a booking ID — useful for riders tracking their rented vehicle.
Response: Same fields as 4.2 plus:
{ "booking_id": 99, "vehicle_id": 42, ... }
4.4 Open Tracker in Browser (Web Route)
GET /tracker/launch
Auth: Keycloak session (kc_auto middleware)
What it does: Generates a Traccar JWT for the logged-in user, then serves a bridge page (traccar_bridge.blade.php) that:
Deletes any existing Traccar browser session (so the JWT always wins)
Redirects to TRACCAR_WEB_URL?token=
How to trigger from sidebar/menu:
- How the Service Works — Internal Flows 5.1 Registering a Vehicle's GPS Device Triggered when: A vehicle is added/updated with an IMEI number via saveTraccarDevice().
uploadvechiclecontroller::update_vehiclestab()
│
└─► UtilityFunctionsController::saveTraccarDevice($request, $email, $vehicleId)
│
└─► TraccarService::saveDevice($request, $email, $vehicleId)
│
├─ getUserByEmail($email) → find/create Traccar user account
├─ syncDevice($request, ...) → create or update Traccar device
├─ linkDeviceToUser(...) → link device to user in Traccar
└─ update addvechicles.traccar_device_id ← cached for fast lookups
Request fields needed: imei, brand, vehicleType, model
5.2 Getting Position (Fast Path)
Once traccar_device_id is cached on the vehicle:
GET /api/vehicles/{id}/position
│
└─► resolveVehiclePosition($vehicle)
│
├─ IF traccar_device_id set → getLatestPositionByDeviceId(id) [1 HTTP call]
└─ IF only imei set → getDeviceByUniqueId(imei) [2 HTTP calls]
→ getLatestPositionByDeviceId(id)
Always register devices via saveTraccarDevice — it sets traccar_device_id and halves position lookup cost.
5.3 JWT Token Generation for Map Access
ensureUserToken($email)
│
├─ resolveTraccarPassword($email, $laravelUser)
│ ├─ IF traccar_password stored in users table → return it [0 HTTP calls]
│ ├─ IF Traccar account exists but no stored password → provisionTraccarPassword()
│ └─ IF no Traccar account → createUser() + store password
│
├─ getSessionJwt($email, $password)
│ ├─ POST /api/session (creates session cookie)
│ └─ POST /api/session/token (exchanges cookie for JWT)
│
├─ IF JWT fails (stale password) → retryWithFreshPassword() → getSessionJwt()
└─ IF all fails → adminSessionJwt() (admin fallback)
- TraccarService Public Methods Reference Method Description Called From saveDevice($request, $email, $vehicleId) Register/update a GPS device for a vehicle saveTraccarDevice() wrappers ensureUserToken($email) Get a Traccar JWT for a user getTraccarToken, /tracker/launch getUserByEmail($email) Fetch Traccar user by email Internal createUser($name, $email, $password) Create a new Traccar user account Internal getDeviceByUniqueId($imei) Fetch Traccar device by IMEI Internal createDevice($name, $imei, ...) Register a new GPS device Internal updateDevice($deviceId, ...) Update an existing GPS device Internal linkDeviceToUser($userId, $deviceId) Give user permission to see device Internal getLatestPosition($imei) Get last GPS position by IMEI resolveVehiclePosition getLatestPositionByDeviceId($id) Get last GPS position by device ID (fast) resolveVehiclePosition
- Database Migrations Two migrations were added:
add_traccar_device_id_to_addvechicles_table
ALTER TABLE addvechicles ADD COLUMN traccar_device_id INT NULL;
add_traccar_password_to_users_table
ALTER TABLE users ADD COLUMN traccar_password VARCHAR(255) NULL;
Run with: php artisan migrate
- How to Add GPS Tracking to a Vehicle (Step by Step) Step 1 — Vehicle must have an IMEI field set When adding/editing a vehicle, pass imei in the request body.
Step 2 — saveTraccarDevice is called automatically
uploadvechiclecontroller.php:1662 calls $this->utilityController->saveTraccarDevice($request, $useremail, $vehicleId) after vehicle save.
Step 3 — Verify registration worked
Check addvechicles table: traccar_device_id should be non-null for that vehicle.
Step 4 — Poll position from frontend
// Every 10 seconds
setInterval(async () => {
const res = await axios.get(/api/vehicles/${vehicleId}/position);
map.setCenter({ lat: res.data.latitude, lng: res.data.longitude });
}, 10000);
- Common Issues & Fixes Symptom Cause Fix No position data available (404) Device registered but GPS hasn't sent data yet Wait for GPS hardware to get a satellite fix and transmit Vehicle not found or no GPS device (404) imei column is null/empty in DB Set IMEI when adding/editing the vehicle JWT works once, then fails Traccar session expired ensureUserToken auto-retries with a fresh password; if still failing check users.traccar_password column traccar_device_id is null saveTraccarDevice was never called or IMEI was blank Re-save the vehicle with a valid IMEI Admin fallback used constantly Traccar user accounts not provisioning Check logs for provisionTraccarPassword - PUT failed; verify admin credentials in .env SSL errors on local dev Self-signed cert Set TRACCAR_VERIFY_SSL=false in .env Traccar returns all users instead of filtered Admin token bypasses ?email= filter This is expected — the service filters client-side, works correctly /tracker/launch shows blank TRACCAR_WEB_URL not set Add TRACCAR_WEB_URL to .env and run php artisan config:clear
- Quick Checklist for a Fresh Setup
☐ Traccar server running and accessible from Laravel server
☐ TRACCAR_API_URL set (internal network URL)
☐ TRACCAR_WEB_URL set (browser-accessible URL)
☐ TRACCAR_API_ADMIN_EMAIL + TRACCAR_API_ADMIN_PASSWORD set
☐ TRACCAR_ENABLED=true
☐ php artisan migrate (adds traccar_device_id + traccar_password columns)
☐ php artisan config:clear
☐ Add a vehicle with a valid IMEI → verify traccar_device_id populates in DB
☐ Call GET /api/traccar/token → verify JWT returned
☐ Call GET /api/vehicles/{id}/position → verify coordinates returned
Top comments (0)