# API & exports

Money Launder exposes a small surface area on purpose — most behavior is config-driven, not API-driven.

## Server export

### `giveDirtyMoney(playerId, amount)`

Adds `amount` of `dirtyMoneyItem` to a player's inventory. Use this from another resource (e.g. a robbery script) to drop dirty cash on a successful score.

```lua
-- Example: hooked from a bank-heist script
exports['6LY_moneylaunder']:giveDirtyMoney(source, 25000)
```

The bridge routes through whichever inventory is active (`ox_inventory` / `qb-inventory` / ESX legacy). Returns nothing — failures are logged server-side.

## Database — what to read directly

For admin tooling or leaderboards, query the two tables directly:

### `tl_moneylaunder_jobs`

One row per laundering run. Columns of interest:

| Column                                   | Type               | Notes                                            |
| ---------------------------------------- | ------------------ | ------------------------------------------------ |
| `id`                                     | VARCHAR(40)        | UUID-style                                       |
| `identifier`                             | VARCHAR(64)        | Player identifier (citizenid / license / steam)  |
| `channel_id`                             | VARCHAR(32)        | `'civilian'` / `'gas_station'` / `'shipment'`    |
| `boss_id`                                | VARCHAR(64)        | Which handler took the drop                      |
| `amount_dirty`                           | INT UNSIGNED       | Dirty $ the player handed in                     |
| `amount_clean`                           | INT UNSIGNED       | Clean $ paid out (after wash rate + fee + theft) |
| `state`                                  | VARCHAR(24)        | See **Job states** below                         |
| `created_at`, `ready_at`, `collected_at` | INT UNSIGNED       | Unix seconds                                     |
| `pickups_mask`, `pickup_count`           | SMALLINT / TINYINT | Bit-flag of collected pickups                    |
| `crates_mask`                            | SMALLINT UNSIGNED  | Bit-flag of loaded crates (shipment\_run)        |

### `tl_moneylaunder_progress`

One row per player.

| Column         | Type              | Notes                             |
| -------------- | ----------------- | --------------------------------- |
| `identifier`   | VARCHAR(64)       | Primary key                       |
| `xp`           | INT UNSIGNED      | Current XP                        |
| `level`        | SMALLINT UNSIGNED | Computed from xp via `levelCurve` |
| `total_washed` | BIGINT UNSIGNED   | Lifetime clean payout             |
| `updated_at`   | INT UNSIGNED      | Last touch (unix seconds)         |

### Job states

These are the values you'll see in `state`:

| State              | Meaning                                                                             |
| ------------------ | ----------------------------------------------------------------------------------- |
| `pending_drop`     | Job created; player hasn't reached the boss with the dirty cash yet                 |
| `pending_delivery` | Drop made; player owes a truck delivery (truck\_delivery / shipment\_run workflows) |
| `washing`          | Wash timer running                                                                  |
| `ready`            | Wash complete; clean cash waiting at pickup points                                  |
| `collected`        | All pickups taken                                                                   |
| `expired`          | Older than `abandonedJobExpiryS`, auto-cleaned                                      |
| `cancelled`        | Player ran `/cancel`; dirty money was refunded                                      |

## Net events

These are internal to the script — listed here so you don't accidentally collide.

### Client (server → client)

* `tl_ml:client:openTablet`
* `tl_ml:client:refreshJobs`
* `tl_ml:client:notify`
* `tl_ml:client:routeToBoss`
* `tl_ml:client:jobReady`
* `tl_ml:client:truckSpawned`
* `tl_ml:client:xpGranted`

### Server (client → server)

* `tl_ml:server:createJob`
* `tl_ml:server:collectJob`
* `tl_ml:server:collectPickup`
* `tl_ml:server:cancelJob`
* `tl_ml:server:requestJobs`
* `tl_ml:server:requestOpen`
* `tl_ml:server:reportDelivery`
* `tl_ml:server:completeDelivery`
* `tl_ml:server:loadCrate`
* `tl_ml:server:spawnTruck`

Don't trigger server events directly from other resources — every server handler validates source, rate-limits, and checks distance. Bypassing those gets the requesting player auto-rejected.

## Hooks not yet exposed

We don't currently emit a public `jobCompleted` event. If you need one (for achievements, leaderboards, anti-cheat ingestion), open a Discord ticket — it's a small bridge change and we can ship it in the next minor.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://6ly-scripts.gitbook.io/product-docs/scripts/money-launder/api-and-exports.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
