Skip to content
Eleva Pro TechnologyEleva Pro Technology
Fleet

API reference

This page is for the developers of the systems that connect to the fleet (HR, planning, reporting). It summarises the REST API: how to authenticate, what each endpoint needs, and what it answers. The full reference, with every field and filter, is the OpenAPI 3.1 file: openapi.yaml.

Every endpoint starts with your installation’s address followed by /api/v1, for example https://fleet.example.com/api/v1. The exact address is shown under Base URL on Settings → Integrations.

Send the token created on that screen with every request:

Authorization: Bearer <token>
Accept: application/json

The browser session of a signed-in user is never accepted. A missing, wrong, revoked or expired token gets 401. The API always answers JSON, with messages in English.

A request must pass three checks:

  1. The token’s abilities. read allows every GET endpoint; write:drivers allows the driver sync (PUT drivers/by-iqama/{iqama} and PATCH drivers/{id}/status). A missing ability gets 403.
  2. The token user’s permissions. The token acts as its user, so that user needs the permission the screens would need (see the table below). Otherwise the answer is 403, for example The token user lacks the "Vehicles::viewAny" permission.
  3. The token user’s projects and cities. A user limited to some projects or cities sees only those vehicles, their records, and the drivers they supervise or who hold one of those vehicles, exactly as on the screens. A record outside that scope answers 404.

Personal data follows the screens too: iqama_number is null unless the token user has the Drivers::view permission. Stored files are never exposed; records only say whether they have one (has_file, has_photo, photos_count).

Each token may make 60 requests a minute. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining; beyond the limit the answer is 429 with a Retry-After header (seconds).

Method Path Ability Permission of the token user
GET /vehicles read Vehicles::viewAny
GET /vehicles/{id} read Vehicles::view
GET /drivers read Drivers::viewAny
GET /drivers/{id} read Drivers::view
GET /contracts read Contracts::viewAny
GET /contracts/{id} read Contracts::view
GET /handovers read VehicleTransfers::viewAny
GET /downtimes read VehicleDowntimes::viewAny
GET /maintenances read VehicleMaintenances::viewAny
GET /fuel-logs read VehicleFuelLogs::viewAny
GET /accidents read Accidents::viewAny
GET /violations read Violations::viewAny
GET /invoices read Reports::MonthlyInvoices
GET /projects read Projects::viewAny
GET /cities read Cities::viewAny
GET /companies read Companies::viewAny
PUT /drivers/by-iqama/{iqama} write:drivers Drivers::create (new driver) or Drivers::edit (existing)
PATCH /drivers/{id}/status write:drivers Drivers::edit

In the role editor, viewAny is the List box of a row and view the View box; Reports::MonthlyInvoices is Monthly invoices under Reports. /invoices lists issued monthly invoices only, with the figures stored when they were issued.

Every list takes:

Parameter Meaning
page Page number, from 1.
per_page 10, 25, 50 or 100 (default 25).
search Free text, up to 100 characters, matched against the list’s main fields (for example the plate number).
sort id, created_at, updated_at, or a field of the list (for example license_plate, start_date).
dir asc or desc.
updated_since A date or date-time: only records changed at or after it, for incremental sync.

And its own filters (ids are comma-separated, for example project=3,4):

List Filters
/vehicles project, city, company, ownership_type (own, lease, replacement)
/drivers status (active, inactive), supervisor, license_type
/contracts vehicle, company, contract_type (own, lease), status (active, upcoming, expired)
/handovers vehicle, driver, open (1: no end date yet, 0: ended)
/downtimes vehicle, contract, status (inactive, replacement)
/maintenances vehicle, driver, maintenance_type
/fuel-logs, /accidents, /violations vehicle, driver
/invoices month (YYYY-MM), contract, company

A wrong parameter (for example per_page=20) gets 422.

A list answers {data, meta, links}; a single record answers {data}. Each record is {id, type, attributes, relationships}: relationships gives the ids of related records (for example the vehicle’s project), which you can read from /projects, /cities and /companies. Dates are YYYY-MM-DD, timestamps ISO 8601, money a JSON number, and translated names {"ar": …, "en": …}.

نافذة طرفيّة
curl -H "Authorization: Bearer $FLEET_TOKEN" \
-H "Accept: application/json" \
"https://fleet.example.com/api/v1/vehicles?per_page=10&project=3"
{
"data": [
{
"id": 12,
"type": "vehicles",
"attributes": {
"license_plate": "ABC 1234",
"brand": { "ar": "تويوتا", "en": "Toyota" },
"vehicle_type": { "ar": "سيدان", "en": "Sedan" },
"vehicle_sub_type": null,
"fuel_type": { "ar": "بنزين 91", "en": "Petrol 91" },
"model_year": 2024,
"ownership_type": "lease",
"vehicle_license_number": "123456789",
"vehicle_license_expiry_date": "2027-03-31",
"has_waei": true,
"owned_cost_bearer": null,
"created_at": "2026-01-15T09:30:00+03:00",
"updated_at": "2026-10-02T14:05:11+03:00"
},
"relationships": {
"project": { "id": 3, "type": "projects" },
"city": { "id": 1, "type": "cities" },
"company": { "id": 5, "type": "companies" }
}
}
],
"meta": { "page": 1, "per_page": 10, "total": 1, "last_page": 1 },
"links": {
"first": "https://fleet.example.com/api/v1/vehicles?per_page=10&project=3&page=1",
"prev": null,
"next": null,
"last": "https://fleet.example.com/api/v1/vehicles?per_page=10&project=3&page=1"
}
}

Creates the driver with this iqama number (201, needs Drivers::create) or updates the existing one (200, needs Drivers::edit), and answers the driver. Repeating the same request changes nothing. The rules are those of the driver form: the iqama number in the path is 10 digits starting with 1 or 2, and the licence number, iqama number and e-mail must be unique. A driver outside the token user’s projects and cities cannot be updated: the iqama number is reported as taken (422).

Field Rule
name Required, up to 255 characters.
license_number Required, up to 255 characters, unique.
license_type_id Required, the id of a licence type.
license_issued_date Required, a date.
license_expiry_date Required, a date on or after license_issued_date.
phone_number Required, up to 20 characters.
email Optional, a valid e-mail, unique.
supervisor_id Required, the id of a user.
status Optional, active or inactive. A new driver is active; an existing one keeps their status.
notes Optional, up to 1000 characters.

The driver’s photo cannot be sent through the API.

Activates or deactivates a driver. Body: {"status": "active"} or {"status": "inactive"}. Answers the driver (200).

Changes made through the API are recorded in the activity log, with the token’s user as the one who made them.

Every error is JSON with a message:

Status When Example
401 No token, or a wrong, revoked or expired one. {"message": "Unauthenticated."}
403 The token lacks the ability, or its user lacks the permission. {"message": "The token user lacks the \"Drivers::view\" permission."}
404 No such record or path, or the record is outside the user’s projects and cities. {"message": "Not found."}
422 Invalid parameters or body; errors lists the messages per field. {"message": "The selected per page is invalid.", "errors": {"per_page": ["The selected per page is invalid."]}}
429 More than 60 requests in a minute with this token. {"message": "Too Many Attempts."}