> For the complete documentation index, see [llms.txt](https://docs.rahe.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rahe.dev/our-scripts/taxi/integration.md).

# Integration

`rahe-taxi` has auto-detection for the most common fuel, vehicle key and garage resources. If you are running one of the supported systems, no setup is required — it just works.

If you use a custom or unsupported resource, you can plug it in by editing the corresponding file under `public/api/`. These files are unencrypted so you can adapt them to your systems.

> The detection runs in a `CreateThread` at resource start and picks the first matching resource (by `GetResourceState`). If none match, an error is printed and you must implement the integration yourself.

***

#### Fuel system <a href="#fuel-system" id="fuel-system"></a>

**File:** public/api/cl\_fuelsystem.lua (client-side)

**Supported out of the box**

* `LegacyFuel`
* `qs-fuelstations`
* `ox_fuel`
* `cdn-fuel`
* `lc_fuel`

**Function to implement**

```lua
function setVehicleFuel(vehicle, fuel)
    -- vehicle: entity handle (client-side)
    -- fuel:    number 0-100
end
```

This is called when an NPC taxi vehicle is spawned and needs its fuel level set.

**Adding your own fuel system**

Add a new `elseif` branch in the detection thread, then add a matching branch in `setVehicleFuel`:

```lua
elseif GetResourceState('my_fuel') ~= 'missing' then
    detectedFuelSystem = 'my_fuel'
```

```lua
elseif detectedFuelSystem == 'my_fuel' then
    exports['my_fuel']:SetFuel(vehicle, fuel)
```

If everything else fails, the script falls back to the native `SetVehicleFuelLevel`.

***

#### Vehicle keys system <a href="#vehicle-keys-system" id="vehicle-keys-system"></a>

**File:** public/api/sv\_vehiclekeys.lua (server-side)

**Supported out of the box**

* `qbx_vehiclekeys`
* `qs-vehiclekeys`
* `cd_garage`
* `wasabi_carlock`
* `Renewed-Vehiclekeys`
* `qb-vehiclekeys`

**Function to implement**

```lua
function unlockVehicleDoors(playerId, vehNetId, vehicle, plate)
    -- playerId: server id of the player
    -- vehNetId: network id of the vehicle
    -- vehicle:  server-side entity handle
    -- plate:    license plate string
    -- return true on success
end
```

Called when a passenger gets into an NPC driver's taxi so the doors can be unlocked for them.

**Adding your own keys system**

```lua
elseif GetResourceState('my_keys') ~= 'missing' then
    detectedKeySystem = 'my_keys'
```

```lua
elseif detectedKeySystem == 'my_keys' then
    exports['my_keys']:GiveTemporaryKey(playerId, plate)
    return true
```

The fallback unlocks the vehicle via the native `SetVehicleDoorsLocked(vehicle, 1)`.

***

#### Garage system <a href="#garage-system" id="garage-system"></a>

**File:** public/api/sv\_garagesystem.lua (server-side)

**Supported out of the box**

* `qbx_vehicles`
* `qb-garages`
* `esx_garage`

**Function to implement**

```lua
function getPlayerOwnedVehicles(playerIdentifier)
    -- playerIdentifier: citizenid (qb/qbx) or identifier (esx)
    -- return an array of vehicle tables in the format below
end
```

Each entry returned **must** have this shape:

```lua
{
    plate = 'ABC123',          -- string, trimmed (no surrounding spaces)
    name  = 'Brand Model',     -- display name shown in the UI
    model = 'taxi',            -- spawn name (must match VEHICLES config key)
}
```

This is used by drivers to choose which of their owned vehicles to put on duty.

**Vehicle naming**

Display names come from the `VEHICLES` config (`shared/vehicles.lua`). If a model is not present there, an error is logged and the vehicle is skipped (qb/qbx) or returned with the raw model name (esx). Add your custom vehicles to that config to fix this.

**Adding your own garage system**

Add detection and a query branch. Example for a custom MySQL-backed garage:

```lua
elseif GetResourceState('my_garage') ~= 'missing' then
    detectedGarageSystem = 'my_garage'
```

```lua
elseif detectedGarageSystem == 'my_garage' then
    local rows = MySQL.query.await('SELECT plate, model FROM my_garage WHERE owner = ?', { playerIdentifier })
    for _, v in ipairs(rows) do
        local info = VEHICLES[v.model]
        if info then
            playerVehicles[#playerVehicles + 1] = {
                plate = v.plate,
                name  = info.brand .. ' ' .. info.name,
                model = v.model,
            }
        end
    end
    return playerVehicles
```

#### Dispatch system <a href="#dispatch-system" id="dispatch-system"></a>

**File:** public/api/cl\_dispatch.lua (client-side)

Used by the in-app safety report feature. When a rider or driver sends a safety report from the UI, the script forwards it to your dispatch / police-alert resource.

**Supported out of the box**

* `ps-dispatch`
* `cd_dispatch`
* `qs-dispatch`
* `qb-policejob` (default `police:server:policeAlert` event)

**Function to implement**

```lua
function alertPolice(vehicleName, vehiclePlate, message, type)
    -- vehicleName:  display name of the vehicle (e.g. "Albany Taxi")
    -- vehiclePlate: license plate string
    -- message:      free-text message written by the player
    -- type:         'rider' or 'driver' — used to pick the locale string
end
```

The localized text is built from `RiderSafetyReport` / `DriverSafetyReport` in the locale files. The current player's coordinates can be obtained inside the function via `GetEntityCoords(PlayerPedId())`.

**Adding your own dispatch system**

Add detection and a handler branch:

```lua
elseif GetResourceState('my_dispatch') ~= 'missing' then
    detectedDispatchSystem = 'my_dispatch'
```

```lua
elseif detectedDispatchSystem == 'my_dispatch' then
    exports['my_dispatch']:CreateAlert({
        title = '10-90 - Taxi Safety Report',
        message = text,
        coords = coords,
        jobs = { 'police' },
    })
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rahe.dev/our-scripts/taxi/integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
