> 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/police-and-medical/cuxial-police/developers.md).

# Exports & events

Public API of Cuxial Police: exports and events to send alerts, read duty, jail players and more.

Send dispatch alerts, read who is on duty, jail players or open the tablet from your own resources. Everything not listed here is internal and can change without notice.

All exports are called as `exports.cuxial_police:Name(...)`.

## Dispatch (server)

### SendDispatchAlert

Sends an alert to the on-duty members of the chosen factions or jobs.

```lua
local id = exports.cuxial_police:SendDispatchAlert(data)
```

| Field                                       | Type             | Description                                                                       |
| ------------------------------------------- | ---------------- | --------------------------------------------------------------------------------- |
| `title`                                     | string           | Title of the alert. Required.                                                     |
| `message`                                   | string           | Body text.                                                                        |
| `type`                                      | string           | Kind of alert. Also decides the faction when `factions` is not given (see below). |
| `severity`                                  | string           | Free label such as `'low'`, `'normal'`, `'high'`, `'critical'`.                   |
| `coords`                                    | vector3 \| table | Position, as `vec3` or `{ x, y, z }`.                                             |
| `street`                                    | string           | Street name.                                                                      |
| `code`                                      | string \| number | Alert code. A sequential number when left out.                                    |
| `reporter`                                  | string           | Who reports.                                                                      |
| `suspect`, `suspects`, `vehicle`, `weapons` | table            | Structured data shown on the alert card.                                          |
| `images`                                    | string\[]        | Image URLs.                                                                       |
| `triage`, `vitals`                          | table            | Medical data for EMS alerts.                                                      |
| `metadata`                                  | table            | Free data.                                                                        |
| `central`                                   | boolean          | `true` also adds the alert to the Central board.                                  |
| `factions`                                  | string\[]        | Receivers: `'police'`, `'ems'`, `'fib'`.                                          |
| `jobs`                                      | string\[]        | Job names. When given, it replaces `factions`.                                    |

**Returns:** `string` with the alert id, or `nil` when the data is invalid.

When neither `jobs` nor `factions` is given, the faction comes from `type`:

| `type`                                                                         | Goes to                                                  |
| ------------------------------------------------------------------------------ | -------------------------------------------------------- |
| `robbery`, `shots`, `vehicle`, `drugs`, `assault`, `chase`, `domestic`, `fire` | Police, and the federal agency when the addon is enabled |
| `medical`, `crash`, `crashfire`, `cardiac`, `overdose`                         | EMS                                                      |
| Anything else                                                                  | Every faction                                            |

```lua
exports.cuxial_police:SendDispatchAlert({
    type = 'robbery',
    title = 'ROBBERY IN PROGRESS',
    message = 'Convenience store, armed suspect',
    severity = 'high',
    coords = GetEntityCoords(GetPlayerPed(source)),
    central = true,
    factions = { 'police' },
})
```

### SendAlert

Shorter form of the same alert.

```lua
exports.cuxial_police:SendAlert(data)
```

It accepts `title`, `message`, `code`, `street`, `distance`, `coords`, `metadata`, `annotation`, `central`, `jobs`, `factions` and `type`. Without `title`, a generic one is used.

### AddCentralAlert

Adds an entry to the Central board without sending it to the sidebars.

```lua
exports.cuxial_police:AddCentralAlert(alert)
```

| Field      | Type             | Description                  |
| ---------- | ---------------- | ---------------------------- |
| `title`    | string           | Title.                       |
| `message`  | string           | Body text.                   |
| `code`     | string \| number | Code. Random when left out.  |
| `street`   | string           | Street name.                 |
| `coords`   | table            | Position.                    |
| `metadata` | table            | Free data.                   |
| `factions` | string\[]        | Factions that see the entry. |

### ClearCentralAlerts

Empties the Central board.

```lua
exports.cuxial_police:ClearCentralAlerts()
```

## Dispatch (client)

### SendDispatchAlert

Sends an alert from the player who reports it. It takes the same fields as the server export, except `code`.

```lua
local sent = exports.cuxial_police:SendDispatchAlert(data)
```

`coords` and `street` are filled in from the player's position when left out. Each player is limited by `dispatch.sendAlertCooldown`. When the sender is not a faction member, `central` and `critical` are ignored.

**Returns:** `boolean`. `false` when `data` is not a table.

```lua
exports.cuxial_police:SendDispatchAlert({
    type = 'medical',
    title = 'MEDICAL EMERGENCY',
    message = 'Unconscious person',
    factions = { 'ems' },
})
```

### Gunshot alerts

Cuxial Police does not detect shots by itself. Trigger this client event from your weapons resource, on the client of the player who fired:

```lua
TriggerEvent('cuxial:gunshot', weaponName, weaponLabel)
```

| Parameter     | Type   | Description                                                              |
| ------------- | ------ | ------------------------------------------------------------------------ |
| `weaponName`  | string | Weapon name, checked against the ignored list (`data.gunshotwhitelist`). |
| `weaponLabel` | string | Name shown in the alert. Optional.                                       |

No alert is sent when the shooter is on duty in a faction, when the job is in `dispatch.ignoredJobs`, when the weapon is ignored or silenced, or with `dispatch.enabled = false`.

## Duty (server)

| Export                                         | Returns       | Description                                                                    |
| ---------------------------------------------- | ------------- | ------------------------------------------------------------------------------ |
| `GetCopsOnDuty()`                              | number        | Members on duty, all factions together.                                        |
| `IsCopOnDuty(src)`                             | boolean       | Whether that player is on duty in a faction.                                   |
| `GetOnDutySources()`                           | number\[]     | Server ids on duty.                                                            |
| `GetOnDutySourcesByFaction(faction)`           | number\[]     | Server ids on duty in `'police'`, `'ems'` or `'fib'`.                          |
| `GetFactionOfSource(src)`                      | string \| nil | Faction of an on-duty player.                                                  |
| `GetCopData()`                                 | table         | Copy of the roster, keyed by server id.                                        |
| `SetCopReference(src, sprite, color, colorId)` | boolean       | Changes the map blip of an on-duty member. A `nil` parameter is left as it is. |

```lua
for _, src in ipairs(exports.cuxial_police:GetOnDutySourcesByFaction('police')) do
    TriggerClientEvent('myresource:notify', src, 'Bank alarm')
end
```

```lua
if exports.cuxial_police:GetCopsOnDuty() < 3 then
    return -- not enough units for this robbery
end
```

## Citizens (server)

### GetCitizenFlags

```lua
local flags = exports.cuxial_police:GetCitizenFlags(citizenid)
```

**Returns:** `{ wanted = boolean, dangerous = boolean }`. Both are `false` for an empty identifier.

### GetAnkleByCitizen

```lua
local ankle = exports.cuxial_police:GetAnkleByCitizen(citizenid)
```

**Returns:** the active ankle monitor of that citizen, or `nil`.

## Home panel (server)

The police home tab shows a list of recent robberies that your resources feed.

| Export                                   | Description                                                               |
| ---------------------------------------- | ------------------------------------------------------------------------- |
| `AddRobbery({ name, location, status })` | Adds an entry. `status` is `'pending'` by default. The last 100 are kept. |
| `GetRobberies()`                         | Returns the list.                                                         |
| `ClearRobberies()`                       | Empties the list.                                                         |

```lua
exports.cuxial_police:AddRobbery({ name = 'Jewellery store', location = 'Vinewood' })
```

## Prison (server)

These exports act on the built-in prison. Months are converted to real time with `prison.monthSeconds` and capped at `limits.maxSentenceMonths`.

| Export                                   | Returns      | Description                                                             |
| ---------------------------------------- | ------------ | ----------------------------------------------------------------------- |
| `Jail(src, months, reason, officerSrc)`  | boolean      | Jails an online player. `reason` and `officerSrc` are optional.         |
| `JailOffline(citizenid, months, reason)` | boolean      | Jails a citizen who is offline.                                         |
| `Unjail(src)`                            | boolean      | Releases an online player.                                              |
| `UnjailOffline(citizenid)`               | boolean      | Releases a citizen by identifier.                                       |
| `IsJailed(src)`                          | boolean      | Whether that player is serving a sentence.                              |
| `GetPrisonerData(src)`                   | table \| nil | `{ jail_time, remaining_sec, months }`. `jail_time` is the months left. |
| `GetActiveSentences()`                   | table        | Online inmates keyed by citizen id: `{ name, months, remaining_sec }`.  |

```lua
exports.cuxial_police:Jail(target, 12, 'Armed robbery', source)
```

## Medical appointments

### Server

| Export                                    | Returns            | Description                                                                                |
| ----------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------ |
| `CreateAppointment(data, opts)`           | row \| nil, reason | Books an appointment.                                                                      |
| `GetPatientAppointments(citizenid, opts)` | table\[]           | Appointments of a patient. `opts`: `kind`, `openOnly`, `limit`.                            |
| `GetAgenda(opts)`                         | table\[]           | Appointments in a time range. `opts`: `from`, `to` (Unix time), `doctorCitizenid`, `kind`. |
| `CancelAppointment(id, reason)`           | boolean, reason    | Cancels an appointment. The patient is notified when `lb-phone` is running.                |
| `CheckInAppointment(id, citizenid)`       | boolean, reason    | Marks the patient as arrived.                                                              |

Fields of `data` for `CreateAppointment`:

| Field             | Type   | Description                                                                                                              |
| ----------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
| `citizenid`       | string | Patient. Required.                                                                                                       |
| `scheduledAt`     | number | Unix time of the appointment. Required; it must be in the future.                                                        |
| `kind`            | string | `'consulta'` (default), `'control'`, `'cura'`, `'analisis'`, `'vacuna'`, `'obstetricia'`, `'psicologia'` or `'cronico'`. |
| `durationMin`     | number | Length in minutes, 5 to 240.                                                                                             |
| `price`           | number | Price. Taken from `appointments.prices` when left out.                                                                   |
| `doctorCitizenid` | string | Assigned doctor.                                                                                                         |

`opts.doctorName` is the name shown as author when no doctor is given.

```lua
local appointment, reason = exports.cuxial_police:CreateAppointment({
    citizenid = citizenid,
    kind = 'consulta',
    scheduledAt = os.time() + 3600,
}, { doctorName = 'Reception' })
```

### Client

For a phone app or any interface of the patient.

| Export                     | Description                                         |
| -------------------------- | --------------------------------------------------- |
| `GetMyAppointments()`      | Returns the player's appointments.                  |
| `ConfirmMyAppointment(id)` | Confirms attendance.                                |
| `CancelMyAppointment(id)`  | Cancels the appointment.                            |
| `CheckInMyAppointment(id)` | Checks in. The player must be at a reception point. |

### InvalidateConditionCache

Call it after writing to the table `cuxial_ems_conditions` from another resource, so the medicine checks reload that patient.

```lua
exports.cuxial_police:InvalidateConditionCache(citizenid)
```

## Settings (server)

### getSetting

Returns the live value of a settings section.

```lua
local value = exports.cuxial_police:getSetting(id)
```

| Parameter | Type   | Description                                                  |
| --------- | ------ | ------------------------------------------------------------ |
| `id`      | string | Section id, such as `'config.jobs'` or `'data.permissions'`. |

**Returns:** the section as a plain table (vectors become `{ x, y, z }`), or `nil` for an unknown id.

```lua
local jobs = exports.cuxial_police:getSetting('config.jobs')
if jobs.policeJobs[jobName] then
    -- the job belongs to the police faction
end
```

## Federal addon (server)

These exports exist only when the addon is enabled.

| Export                                        | Returns      | Description                                                                                 |
| --------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------- |
| `FibGetCase(id)`                              | table \| nil | A case file.                                                                                |
| `FibAddTimeline(id, kind, actor, text, data)` | boolean      | Adds an entry to the timeline of a case. `false` when the case does not exist.              |
| `FibGetOrgHeat(gangId)`                       | number       | Heat of an organisation; `0` when unknown.                                                  |
| `FibCitizenFlags(citizenid)`                  | table \| nil | `{ watchlist, threat, org, warrant }`, or `nil` when the agency has nothing on the citizen. |
| `FibActiveArrestWarrant(citizenid)`           | table \| nil | `{ id, number, expires_at, case_id }` of the active arrest warrant.                         |
| `FibDevicesNear(coords, radius)`              | table\[]     | Active devices around a point: `{ id, kind, dist }`. `radius` is `30.0` by default.         |

```lua
local warrant = exports.cuxial_police:FibActiveArrestWarrant(citizenid)
if warrant then
    print(('Arrest warrant %s'):format(warrant.number))
end
```

## Client exports

### cuxial\_mdt

Opens the tablet. It is also the handler of the `cuxial_mdt` item.

```lua
exports.cuxial_police:cuxial_mdt()
```

The exports `prescription`, `death_certificate`, `fib_camera`, `fib_mic` and `fib_gps` are item handlers for the inventory and are not meant to be called by hand.

## Client events

Local events to drive the interface from another client resource, such as a radial menu.

| Event                     | Parameters | What it does                    |
| ------------------------- | ---------- | ------------------------------- |
| `cuxial:tablet:open`      | none       | Opens the tablet.               |
| `cuxial:tablet:close`     | none       | Closes the tablet.              |
| `cuxial:tablet:toggle`    | none       | Opens or closes the tablet.     |
| `cuxial:quickmenu:open`   | none       | Opens the quick menu.           |
| `cuxial:quickmenu:close`  | none       | Closes the quick menu.          |
| `cuxial:quickmenu:toggle` | none       | Opens or closes the quick menu. |
| `cuxial:duty:toggle`      | none       | Goes on or off duty.            |
| `cuxial:duty:set`         | `state`    | Sets duty to `true` or `false`. |
| `cuxial:duty:get`         | `cb`       | Calls `cb(onDuty)`.             |

```lua
TriggerEvent('cuxial:tablet:open')
```

Events you can listen to:

| Event                                   | Parameters | When                                        |
| --------------------------------------- | ---------- | ------------------------------------------- |
| `cuxial_police:client:SetDuty`          | `state`    | The player's duty state changed.            |
| `cuxial_police:client:NewAlert`         | `alert`    | The player received a dispatch alert.       |
| `cuxial_police:client:JobChangeCleanup` | none       | The player left the faction or changed job. |

```lua
RegisterNetEvent('cuxial_police:client:SetDuty', function(state)
    print(state and 'On duty' or 'Off duty')
end)
```

## Server events

| Event                                   | Parameters            | When                                                                                |
| --------------------------------------- | --------------------- | ----------------------------------------------------------------------------------- |
| `cuxial_police:internal:JobChanged`     | `src, oldJob, newJob` | A player's job changed.                                                             |
| `cuxial_police:internal:PrisonReleased` | `citizenid, cause`    | An inmate of the built-in prison was released. `cause` is `'served'` or `'police'`. |
| `cuxial_police:settingsApplied`         | `id`                  | A settings section was applied. Also triggered on the client.                       |

```lua
AddEventHandler('cuxial_police:internal:PrisonReleased', function(citizenid, cause)
    print(('%s released (%s)'):format(citizenid, cause))
end)
```

## State bags

| State bag    | On     | Value                                      |
| ------------ | ------ | ------------------------------------------ |
| `cuffed`     | Player | `true` while the player is cuffed.         |
| `escorted`   | Player | `true` while the player is being escorted. |
| `escortedBy` | Player | Server id of the escorting officer.        |

```lua
if Player(source).state.cuffed then return end
```


---

# 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/police-and-medical/cuxial-police/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.
