> For the complete documentation index, see [llms.txt](https://5code.gitbook.io/5code-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://5code.gitbook.io/5code-docs/5code-recognition/getting-started/installation.md).

# Installation

Twelve steps. Read [Requirements](/5code-docs/5code-recognition/getting-started/requirements.md) first.

{% hint style="info" %}
The zip also ships `installation.md` in its root. It contains this same walkthrough plus a second part — **Installation via AI** — with the hard rules and the question list to hand to an AI assistant if you want one to do the install for you.
{% endhint %}

## 1. Check the requirements

FXServer artifact **7290 or newer**, OneSync **on**, `oxmysql` running, MySQL 8.0+ or MariaDB 10.4+. Optional: ox\_lib, a voice system, an appearance script, a death script, an MDT.

## 2. Place the folder

Drop the folder into `resources/[scripts]/`.

{% hint style="warning" %}
**Keep the name `5code-recognition`.** Other scripts call `exports['5code-recognition']:…`, the inventory item export is registered as `5code-recognition.useItem`, and the docs assume that name everywhere. Renaming the folder breaks all of it.
{% endhint %}

## 3. Add it to `server.cfg`

Start it **after** everything it integrates with, so `'auto'` can find them at boot.

```cfg
ensure oxmysql
ensure ox_lib            # optional
ensure qbx_core          # or qb-core / es_extended / nothing (standalone)
ensure ox_inventory      # your inventory
ensure pma-voice         # your voice system
ensure illenium-appearance
ensure 5code-recognition
```

Order in one line: `oxmysql` → framework → inventory → (`ox_lib`) → voice → ambulance / police / MDT / evidence / HUD → **us**.

{% hint style="info" %}
Got the order wrong? A bridge whose script starts *after* us re-resolves itself once, so most mistakes fix themselves without a restart. ESX has one real exception — see step 8.
{% endhint %}

## 4. Secrets and webhooks

They go in `config_server.lua` or in convars — **never** in `config.lua`, which every player downloads.

```cfg
set recognition_secret "YOUR_LONG_RANDOM_TEXT"            # optional: auto-generated if empty
set recognition_webhook_default "[YOUR WEBHOOK URL]"
set recognition_webhook_proofs  "[YOUR WEBHOOK URL]"
```

{% hint style="danger" %}
Use **`set`**, never **`setr`**. A `setr` convar is sent to every connected player, so `setr recognition_secret "…"` hands your secret and your webhook URLs to everyone on the server.
{% endhint %}

Set `recognition_secret` **before the first start** if you can. Leave it empty and the script generates one into the database instead, which is weaker (anyone with database access can read it) and prints a warning at every boot. Once set, never change it: a changed secret is refused at boot, because voices, voiceprint codes, tattoo codes and the proof log all depend on it.

Full list: [Files & Convars](/5code-docs/5code-recognition/configuration/files-and-convars.md).

## 5. Edit `config.lua`

The three things worth doing on day one:

```lua
Config.Framework = 'auto'                        -- leave on auto, or pin your framework
Config.Jobs.Police = { 'police' }               -- ships with 'police'; add your other departments
Config.Implant.Clinics = { ... }                 -- move the clinic where you want it
```

Everything else has a working default. See [Configuration](/5code-docs/5code-recognition/configuration/files-and-convars.md).

{% hint style="warning" %}
**Police job names are the number one support ticket.** `Config.Jobs.Police` decides who gets the capped memory from a camera report and who can be sent statements; `Config.Jobs.HintJobs` decides who sees the "possible match" line. If your department is called `lspd` and its job has no `leo` type, the defaults give them nothing. On QBCore and Qbox you can also rely on `job.type = 'leo'` through `Config.Jobs.AcceptTypes`. `recognition:selftest` names any job in the lists that your server does not have.
{% endhint %}

## 6. Add the five items

`voice_changer`, `hidden_camera`, `magnetic_scanner`, `recognition_battery`, `recognition_report`. Paste-ready definitions per inventory are in [Items](/5code-docs/5code-recognition/getting-started/items.md) and in the `install/items/` folder of the zip.

Running standalone without an inventory? Skip it — items are then kept by the script and the console says so: `[5code-recognition] standalone: items are kept by the script (use /recognition:use).`

## 7. Admin permission

```cfg
add_ace group.admin recognition.admin allow
add_principal identifier.license:YOUR_LICENSE_HERE group.admin
```

Lighter staff roles get one child ACE each instead of the parent: `recognition.admin.view`, `.edit`, `.export`, `.classifier`, `.identity`, `.settings`. See [Admin & Permissions](/5code-docs/5code-recognition/configuration/admin-and-permissions.md).

{% hint style="danger" %}
Never give `recognition.admin` to a broad group such as `builtin.everyone`. It reads memories, proofs and identity data for every character on the server.
{% endhint %}

## 8. Character data (framework-specific)

So a deleted character's recognition identity goes with it:

{% tabs %}
{% tab title="Qbox" %}
Add one entry to `qbx_core/config/server.lua`:

```lua
characterDataTables = {
    -- ... keep every existing entry ...
    {'recognition_identities', 'identifier'},
},
```

If you use an external character selector, `useExternalCharacters` must be `true`.
{% endtab %}

{% tab title="ESX" %}
`esx_multicharacter` builds its clean-up list **only when it starts**, so our table has to exist by then. Pick one:

1. **Recommended:** import `sql/install.sql` once by hand (HeidiSQL, phpMyAdmin) before the next start. It is idempotent — running it twice changes nothing.
2. Or put `ensure 5code-recognition` **before** `ensure esx_multicharacter` (with `oxmysql` and `es_extended` still before both) and restart the server once after the very first start.

Check it: create a test character, delete it, and confirm its row in `recognition_identities` is gone.
{% endtab %}

{% tab title="0R Multicharacter v3" %}
Add our character-keyed tables to its `config/database.lua` `Database.List`, in each framework section you use, using the same entry format as the rows already there:

| Table                        | Columns                      |
| ---------------------------- | ---------------------------- |
| `recognition_identities`     | `identifier`                 |
| `recognition_memories`       | `observer_key`, `target_key` |
| `recognition_familiarity`    | `observer_key`, `target_key` |
| `recognition_introductions`  | `observer_key`, `target_key` |
| `recognition_devices`        | `owner_key`                  |
| `recognition_reports`        | `author_key`, `holder_key`   |
| `recognition_death_sessions` | `char_key`                   |

Do **not** list `recognition_scans`, `recognition_proofs`, `recognition_admin_log` or `recognition_anomalies`. The proof and admin logs are tamper-evident: deleting rows out of the middle makes `recognition:verifyproofs` report them as tampered.
{% endtab %}

{% tab title="QBCore & others" %}
Nothing to install. QBCore deletes characters from a fixed list of tables and fires no event, so our own character clean-up job handles it (every 6 h by default, plus a 10 s check when it sees a delete happen). The same job covers UM, 17mov, CodeM, OP, ak47 and VMS selectors on any framework.
{% endtab %}
{% endtabs %}

## 9. Start it

```cfg
ensure 5code-recognition
```

You should see these lines:

```
[5code-recognition] Schema ensured (mysql 8.0.39).
[5code-recognition] Integrations: framework=qbx inventory=ox_inventory voice=pma-voice appearance=illenium-appearance tattoos=illenium-appearance death=qbx_medical police=qbx_police mdt=none evidence=none target=none textui=native hud=jg-hud screenshot=builtin
[5code-recognition] Full scan time with current settings: 90 s.
[5code-recognition] Resource started successfully (v1.0.0).
[5code-recognition] Up to date (1.0.0).
```

The last line arrives about **eight seconds** after the others, and is silently skipped if the update check cannot reach GitHub — its absence is not a fault.

Then run the self-test in the **server console**:

```
recognition:selftest
```

Every line should say **PASS**.

## 10. Test in game with a friend

Face your friend and press **F3**. **Scan person to memory** is already marked: press **ENTER**, then **ENTER** again to start on the orange arrow, and talk. Then have them put a mask on and scan again. Then check the result from the **server console**:

```
recognition:check <yourId> <friendId>
```

{% hint style="info" %}
The in-game panel (`/recognition:admin <idA> <idB>`) refuses a pair that includes your own character, so a third staff member should open it, or use the console line above. See [First Test](/5code-docs/5code-recognition/getting-started/first-test.md) step 6.
{% endhint %}

Full walkthrough: [First Test (5 minutes)](/5code-docs/5code-recognition/getting-started/first-test.md).

## 11. Optional extras

* JG HUD offset and the optional hide stack — [HUDs](/5code-docs/5code-recognition/integrations/huds.md)
* MDT push for camera reports and statements — [Police, MDT & Evidence](/5code-docs/5code-recognition/integrations/police-mdt-evidence.md)
* Lab ID from your evidence script — same page
* A screenshot resource for photos — [Photos & Screenshots](/5code-docs/5code-recognition/configuration/photos.md)
* A nametag driver so masked players lose their floating name — [Nametags & Chat](/5code-docs/5code-recognition/integrations/nametags-and-chat.md)
* Target mode instead of the **F3** menu — [Target, Text UI, Progress, Notify & Emotes](/5code-docs/5code-recognition/integrations/ui-helpers.md). Printing camera recordings needs the F3 menu, so it is not available in target or prompt mode.

## 12. If something is wrong

Every boot line has a fix on the [Troubleshooting](/5code-docs/5code-recognition/reference/troubleshooting.md) page. Two quick ones:

* **"My changes don't apply."** You are almost always editing a different copy of the folder than the one the server loaded, or on a different server than the one you are testing on. Check the path the console prints.
* **Missing item definitions.** `[5code-recognition] Missing item definitions: voice_changer, hidden_camera.` → step 6.


---

# 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://5code.gitbook.io/5code-docs/5code-recognition/getting-started/installation.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.
