> For the complete documentation index, see [llms.txt](https://mango-5m.gitbook.io/mango5m-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mango-5m.gitbook.io/mango5m-docs/resources/mango-dispatch/developer-guide/registering-units.md).

# Registering Units

Put players on the air from your own duty system or phone.

Job-based recipients cover most servers. Registration covers the rest: a duty system, a callsign board, a phone app - anything that decides who is on the air by something other than a job name.

```lua
exports['mango_dispatch']:RegisterUnit(source, {
    name = 'Officer Reyes',
    deptName = 'LSPD',
    deptColor = '#3b82f6',
    tag = '1-ADAM-12',
})
```

### Fields

| Field        | Type   | Used for                                                                                        |
| ------------ | ------ | ----------------------------------------------------------------------------------------------- |
| `name`       | string | Overrides the framework name for this unit - callsign-style display names, for instance         |
| `deptId`     | any    | Your own department key. Passed straight back in `GetUnits()`, never interpreted                |
| `deptName`   | string | Department label. Falls back to the framework job label                                         |
| `deptColor`  | string | Hex colour for rosters that render one                                                          |
| `tag`        | string | Callsign                                                                                        |
| `identifier` | string | Override the identifier. Only needed if your system keys players differently from the framework |

Every field is optional - `RegisterUnit(source, {})` is enough to put someone on the air.

The registering resource's name is recorded automatically, so `Config.Debug = true` tells you exactly who put a unit on the air.

### Taking them off

```lua
exports['mango_dispatch']:UnregisterUnit(source)
```

Both directions push the new state to that player immediately: their alerts and window are cleared the moment they are unregistered. Disconnecting cleans up on its own.

{% hint style="warning" %}
Registration lasts for the **session**, not forever - it is in memory and does not survive a restart of `mango_dispatch`. A duty system should re-register its players on `onResourceStart`.
{% endhint %}

### How it interacts with jobs

`Config.Recipients.mode` decides whether registration matters at all:

| Mode               | Registered player is a unit?                   |
| ------------------ | ---------------------------------------------- |
| `'both'` (default) | Yes                                            |
| `'registered'`     | Yes - and job-based units are ignored entirely |
| `'job'`            | No. Registration is ignored                    |

So a server that wants "on the air" to mean strictly "clocked in through my duty system" should set `mode = 'registered'` and register from that system.

### Reading the roster

```lua
for _, unit in ipairs(exports['mango_dispatch']:GetUnits()) do
    print(unit.source, unit.name, unit.tag, unit.deptName, unit.jobName)
end
```

Registered fields and framework fields are merged - so a unit registered with only a `tag` still reports their job name and label from the framework.
