> For the complete documentation index, see [llms.txt](https://docs.cuxial.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cuxial.com/scripts/core/cuxial-garages/developers.md).

# Exports & events

Public API of Cuxial Garages: exports for keys, house garages, impound and vehicle cleanup.

Give and check vehicle keys, open a house garage, impound a vehicle or start a cleanup from your own resources. Resources written for `qbx_vehiclekeys` need no changes.

{% hint style="info" %}
The key exports exist only with `enabled = true` in `data/keys.lua`, and the cleanup exports only with `enabled = true` in `data/carwipe.lua`.
{% endhint %}

## Server exports

### GiveKeys

Gives a player the key of a plate. Does nothing if the player already has it.

```lua
exports.cuxial_garages:GiveKeys(source, plate)
```

| Parameter | Type   | Description                                                               |
| --------- | ------ | ------------------------------------------------------------------------- |
| `source`  | number | Server id of the player.                                                  |
| `plate`   | string | Plate of the vehicle. Spaces around it are ignored and it is upper-cased. |

**Returns:** `boolean`. `true` when the player ends up with the key.

```lua
exports.cuxial_garages:GiveKeys(source, 'ABC12345')
```

### HasKeys

Tells whether a player carries the key of a plate.

```lua
local has = exports.cuxial_garages:HasKeys(source, plate)
```

| Parameter | Type   | Description              |
| --------- | ------ | ------------------------ |
| `source`  | number | Server id of the player. |
| `plate`   | string | Plate of the vehicle.    |

**Returns:** `boolean`.

```lua
if not exports.cuxial_garages:HasKeys(source, plate) then return end
```

### RemoveKeys

Removes every key of that plate from the player's inventory.

```lua
exports.cuxial_garages:RemoveKeys(source, plate)
```

| Parameter | Type   | Description              |
| --------- | ------ | ------------------------ |
| `source`  | number | Server id of the player. |
| `plate`   | string | Plate of the vehicle.    |

**Returns:** `boolean`. `true` when at least one key was removed.

```lua
exports.cuxial_garages:RemoveKeys(source, plate)
```

### ImpoundStoredVehicle

Sends a vehicle to the impound from its database id, without an officer. Made for vehicles that are stored: it does not remove a vehicle that is out in the world.

```lua
local result = exports.cuxial_garages:ImpoundStoredVehicle(data)
```

| Parameter        | Type   | Description                                                                           |
| ---------------- | ------ | ------------------------------------------------------------------------------------- |
| `data.id`        | number | Id of the vehicle in the vehicle table. Required.                                     |
| `data.cost`      | number | Fee to retrieve it. Defaults to `defaultPrice` from `data/impound.lua`.               |
| `data.reason`    | string | Reason shown to the owner. Up to 255 characters.                                      |
| `data.sentBy`    | string | Name shown as the person who impounded it. Up to 100 characters.                      |
| `data.job`       | string | Job recorded as the origin of the impound.                                            |
| `data.depot`     | string | Id of the depot that holds it. Without it, the vehicle can be retrieved at any depot. |
| `data.fromState` | number | State the vehicle must be in. Defaults to stored (`1`).                               |

**Returns:** `table`. On success `{ ok = true, cost, depot, depotLabel }`. On failure `{ ok = false, reason }`, where `reason` is `'bad_request'`, `'no_vehicle'` or `'not_stored'`.

```lua
local result = exports.cuxial_garages:ImpoundStoredVehicle({
    id = vehicleId,
    cost = 2500,
    reason = 'Seized by court order',
    sentBy = 'Department of Justice',
    job = 'police',
})
if result.ok then print('Impounded for $' .. result.cost) end
```

### GetVehicleMdtInfo

Returns the nickname and the impound record of a plate. Made for police tablets.

```lua
local info = exports.cuxial_garages:GetVehicleMdtInfo(plate)
```

| Parameter | Type   | Description                |
| --------- | ------ | -------------------------- |
| `plate`   | string | Plate of an owned vehicle. |

**Returns:** `table` or `nil` when the plate has no owner.

| Field      | Type          | Description                                                                                                                                       |
| ---------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nickname` | string \| nil | Nickname set by the owner.                                                                                                                        |
| `impound`  | table \| nil  | `nil` when the vehicle is not impounded. Otherwise `depot`, `cost`, `reason`, `selfRetrievable`, `sentBy`, `authorizedBy` and `date` (Unix time). |

```lua
local info = exports.cuxial_garages:GetVehicleMdtInfo('ABC12345')
if info and info.impound then
    print(('Impounded by %s: %s'):format(info.impound.sentBy, info.impound.reason or '-'))
end
```

### StartCarWipe

Starts a vehicle cleanup after a countdown shown to every player.

```lua
local ok, message = exports.cuxial_garages:StartCarWipe(seconds)
```

| Parameter | Type   | Description                                                                     |
| --------- | ------ | ------------------------------------------------------------------------------- |
| `seconds` | number | Countdown in seconds. Optional; `countdown` from `data/carwipe.lua` by default. |

**Returns:** `boolean, string`. `false` when a cleanup is already in progress. The string is the message to show.

```lua
local ok, message = exports.cuxial_garages:StartCarWipe(90)
print(message)
```

### CancelCarWipe

Cancels the cleanup in progress.

```lua
local ok, message = exports.cuxial_garages:CancelCarWipe()
```

**Returns:** `boolean, string`. `false` when no cleanup is in progress.

### IsWipeInProgress

Tells whether a cleanup countdown is running.

```lua
local running = exports.cuxial_garages:IsWipeInProgress()
```

**Returns:** `boolean`.

## Client exports

### GiveKeys

Asks the server for the key of a plate for the local player. The server only grants it when the player owns the vehicle or the plate has no owner.

```lua
exports.cuxial_garages:GiveKeys(plate, vehicleEntity)
```

| Parameter       | Type   | Description                                                                                                                                                               |
| --------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plate`         | string | Plate of the vehicle.                                                                                                                                                     |
| `vehicleEntity` | number | Vehicle handle. Optional. When given, the player can use that vehicle at once, without waiting for the item. Use it for vehicles you spawn yourself, such as test drives. |

```lua
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
exports.cuxial_garages:GiveKeys(GetVehicleNumberPlateText(vehicle), vehicle)
```

### HasKeys

Tells whether the local player carries the key of a plate. It asks the server, so call it from a thread.

```lua
local has = exports.cuxial_garages:HasKeys(plate)
```

**Returns:** `boolean`.

### RemoveKeys

Removes the key of a plate from the local player.

```lua
exports.cuxial_garages:RemoveKeys(plate)
```

### IsVehicleAccessible

Tells whether the local player can use a vehicle: with its key, or through the shared keys of their job. It asks the server, so call it from a thread.

```lua
local allowed = exports.cuxial_garages:IsVehicleAccessible(vehicle)
```

| Parameter | Type   | Description     |
| --------- | ------ | --------------- |
| `vehicle` | number | Vehicle handle. |

**Returns:** `boolean`.

```lua
if not exports.cuxial_garages:IsVehicleAccessible(cache.vehicle) then return end
```

### OpenGarage

Opens a house garage at a position given by your housing resource. The garage is not saved in the database and draws no marker: your resource handles the interaction point.

```lua
exports.cuxial_garages:OpenGarage(id, opts)
```

| Parameter       | Type     | Description                                                                                |
| --------------- | -------- | ------------------------------------------------------------------------------------------ |
| `id`            | string   | Unique id of the garage, up to 64 characters. Vehicles stored there stay tied to this id.  |
| `opts.coords`   | vector4  | Access position, also used as the parking spot when no `spawns` are given. Required.       |
| `opts.category` | string   | `'car'`, `'motorcycle'`, `'air'` or `'sea'`. Optional; all categories by default.          |
| `opts.label`    | string   | Name shown in the interface. Optional, up to 48 characters.                                |
| `opts.capacity` | number   | Vehicles per player, from 1 to 100. Optional. Applied only with `capacity.enabled = true`. |
| `opts.spawns`   | table\[] | Parking spots as `{ x, y, z, h }`. Optional, up to 16, each within 30 metres of `coords`.  |

```lua
exports.cuxial_garages:OpenGarage('house:' .. property.id, {
    coords = vector4(x, y, z, heading),
    category = 'car',
    label = 'Home garage',
    capacity = 4,
})
```

### StoreVehicle

Stores the vehicle the local player is driving in a house garage. Does nothing if the player is not the driver.

```lua
exports.cuxial_garages:StoreVehicle(id, opts)
```

| Parameter | Type   | Description                                                                             |
| --------- | ------ | --------------------------------------------------------------------------------------- |
| `id`      | string | Id of the garage, the same one used with `OpenGarage`.                                  |
| `opts`    | table  | Optional. Same fields as `OpenGarage`. Without `coords`, the player's position is used. |

```lua
exports.cuxial_garages:StoreVehicle('house:' .. property.id, { category = 'car' })
```

{% hint style="warning" %}
`OpenGarage` and `StoreVehicle` only work with `externalGarages = true` in `shared/config.lua`. The server also checks that the player is within `interactDistance` (8 metres by default) of `coords`, and accepts up to 25 house garages per player and session.
{% endhint %}

### OpenImpound

Opens the impound form for the vehicle nearest to the local player, as `/impound` does. The player still needs an impound job.

```lua
exports.cuxial_garages:OpenImpound()
```

## qbx\_vehiclekeys compatibility

Cuxial Garages answers these calls under the `qbx_vehiclekeys` name, so resources that use them keep working:

| Call                                                                | Behaviour                                                                                          |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `exports.qbx_vehiclekeys:GiveKeys(source, vehicle)`                 | Server. `vehicle` is a vehicle handle or a plate.                                                  |
| `exports.qbx_vehiclekeys:HasKeys(source, plate)`                    | Server. Same as `HasKeys` above.                                                                   |
| `exports.qbx_vehiclekeys:RemoveKeys(source, plate)`                 | Server. Same as `RemoveKeys` above.                                                                |
| `lib.callback('qbx_vehiclekeys:server:giveKeys', false, cb, netId)` | Called from the client. Grants the key of that vehicle when the player owns it or it has no owner. |

```lua
exports.qbx_vehiclekeys:GiveKeys(source, vehicle)
```

## State bags

| State bag        | On      | Meaning                                                                                        |
| ---------------- | ------- | ---------------------------------------------------------------------------------------------- |
| `vehicleid`      | Vehicle | Database id of an owned vehicle delivered by a garage. Vehicles without it count as not owned. |
| `doorslockstate` | Vehicle | Door lock state set by the key system. Above `1` = locked.                                     |
| `ignoreLocks`    | Vehicle | Set it to `true` from your resource to keep a vehicle out of the lock system.                  |
| `rentalcode`     | Vehicle | Ticket code of a rented vehicle.                                                               |

```lua
Entity(vehicle).state:set('ignoreLocks', true, true)
```

## Events

Cuxial Garages exposes no public events. Use the exports above.

## Custom integrations

Three options point to a resource by name. To use your own resource instead of the default, it must provide these server exports:

| Option                                    | Exports your resource must provide                                                                                      |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `dispatch.resource` in `data/keys.lua`    | `SendDispatchAlert(data)`                                                                                               |
| `license.resource` in `data/rental.lua`   | `GetAvailableCards()` returns a list of `{ type, label }`. `GetPlayerLicenses(citizenid)` returns a list of `{ type }`. |
| `finance.resource` in `shared/config.lua` | `getPlayerFinancedVehicles(citizenid)`, `getFinanceByPlate(plate)` and `makeFinancePayment(source, plate)`              |

The theft alert sent to `SendDispatchAlert`:

```lua
{
    title = 'Vehicle theft',      -- translated text
    type = 'vehicle',
    code = '10-72',
    coords = { x = 0.0, y = 0.0, z = 0.0 },
    vehicle = { plate = 'ABC12345' },
    central = true,
}
```


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.cuxial.com/scripts/core/cuxial-garages/developers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
