> 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-cmservices/developers.md).

# Exports & events

Public API of Cuxial Community Service: server exports to read, add and remove sanctions.

Read a player's sanction, or give and remove community service from your own resources, such as an admin menu or a web panel. The API is three server exports; the script exposes no public events.

## Server exports

### GetPlayerPunishment

Returns the active sanction of a player.

```lua
exports.cuxial_cmservices:GetPlayerPunishment(player, punishmentType)
```

| Parameter        | Type            | Description                                                                                              |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------- |
| `player`         | number \| table | Server id of a connected player, or a player table that carries `citizenid` (or `PlayerData.citizenid`). |
| `punishmentType` | string          | `'comserv'` or `'jail'`.                                                                                 |

**Returns:** `table | false`. The sanction, or `false` when the player has none of that type.

| Field    | Type   | Description                                          |
| -------- | ------ | ---------------------------------------------------- |
| `count`  | number | Community service: tasks left. Jail: minutes served. |
| `all`    | number | Community service: tasks given. Jail: total minutes. |
| `reason` | string | Reason written by staff.                             |
| `start`  | number | Unix time when the sanction was given.               |
| `admin`  | table  | Who gave it: `name` and `identifier`.                |

```lua
local jail = exports.cuxial_cmservices:GetPlayerPunishment(source, 'jail')
if jail then
    print(('%d minutes left'):format(jail.all - jail.count))
end
```

### AddCommunityService

Gives community service tasks to a character. It works with the player connected (applied at once) or disconnected (applied on their next login). If the character already has community service, the tasks are added to it and the reason is appended.

```lua
exports.cuxial_cmservices:AddCommunityService(citizenid, amount, reason, admin)
```

| Parameter   | Type         | Description                                                                        |
| ----------- | ------------ | ---------------------------------------------------------------------------------- |
| `citizenid` | string       | Character identifier.                                                              |
| `amount`    | number       | Tasks to add. From 1 to 10000; decimals are rounded down.                          |
| `reason`    | string       | Reason. Required. Cut at 250 characters.                                           |
| `admin`     | table \| nil | Who gives it: `{ name = string, identifier = string }`. Both default to `'panel'`. |

**Returns:** `boolean, string`. `true` plus `'online'` or `'offline'`, according to whether the player was connected. `false` plus the cause when the request is refused:

| Second value                                 | Cause                                  |
| -------------------------------------------- | -------------------------------------- |
| `'citizenid inválido'`                       | `citizenid` is not a non-empty string. |
| `'cantidad inválida'`                        | `amount` is out of range.              |
| `'sin motivo'`                               | `reason` is empty.                     |
| `'el jugador está en cárcel administrativa'` | The character has jail time active.    |
| `'no se pudo guardar en la base de datos'`   | The database write failed.             |

```lua
local ok, detail = exports.cuxial_cmservices:AddCommunityService('ABC12345', 10, 'Vehicle deathmatch', {
    name = GetPlayerName(source),
    identifier = 'ABC00001',
})

if not ok then
    print('Refused: ' .. detail)
end
```

{% hint style="warning" %}
The export does not check who calls it. Check the permission of the staff member in your own resource before calling.
{% endhint %}

### RemoveCommunityService

Removes the community service of a character. A connected player is moved to the exit point and notified.

```lua
exports.cuxial_cmservices:RemoveCommunityService(citizenid, admin)
```

| Parameter   | Type         | Description                                                        |
| ----------- | ------------ | ------------------------------------------------------------------ |
| `citizenid` | string       | Character identifier.                                              |
| `admin`     | table \| nil | Who removes it: `{ name = string }`. `name` defaults to `'panel'`. |

**Returns:** `boolean, string`. `true` plus `'online'` or `'offline'`. `false` plus the cause:

| Second value              | Cause                                          |
| ------------------------- | ---------------------------------------------- |
| `'citizenid inválido'`    | `citizenid` is not a non-empty string.         |
| `'no tiene comunitarias'` | The character has no community service active. |

```lua
local ok, detail = exports.cuxial_cmservices:RemoveCommunityService('ABC12345', {
    name = GetPlayerName(source),
})
```


---

# 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-cmservices/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.
