> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aps-store.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Phone integration

Built-in support for sd-phone, LB Phone, 17Movement Phone, YSeries, qs-smartphone-pro, GKSPhone and qb-phone. Any other phone can be connected through `Config.PhoneCustom`.

## Supported phones

| Phone | Notifications | Mails | City Hall app | PC Mail app |
| - | - | - | - | - |
| `sd-phone` | ✓ | ✓ | ✓ | read + write |
| `lb-phone` | ✓ | ✓ | ✓ | full |
| `17mov_Phone` | ✓ | ✓ | ✓ | read-only |
| `yseries` | ✓ | ✓ | ✓ | — |
| `qs-smartphone-pro` | ✓ | ✓ | ✓ | — |
| `gksphone` | ✓ | ✓ | — | — |
| `qb-phone` | ✓ | ✓ | — | — |
| `custom` | your own `notify` / `mail` functions in `Config.PhoneCustom` (`config/config.server.lua`), e.g. for okokPhone | | | |

sd-phone is checked first because it also answers to the names `lb-phone`, `qb-phone`, `gksphone`, `yseries` and `qs-smartphone`.

```lua theme={null}
-- config/config.server.lua — used when Config.Phone.system = 'custom'
Config.PhoneCustom = {
    notify = function(source, title, text) end,
    mail   = function(source, subject, body, sender) end,
}
```

## What it adds

* **A read-only City Hall app** on the phone: unpaid bills and insurance and documents that expire soon, plus a button that sets a waypoint to the nearest City Hall. Players can't pay or order anything from the phone, so they still have a reason to visit City Hall.
* **Notifications** when a bill is issued or paid, a license is earned, a document is ordered, a vehicle is insured or a business is registered.
* **An email** for every new bill, including the violation and the due date.
* **A Mail app on the PC** that shows the player's phone mailbox (see below).

The phone is detected automatically. Nothing else needs to be installed: the app page ships in `web/phone/`.

## Configuration

```lua theme={null}
Config.Phone = {
    system = 'auto',                  -- 'auto' | a phone from the table above | 'custom' | 'none'

    app = {
        enabled        = true,
        identifier     = 'aps_cityhall',
        name           = 'City Hall',
        description    = 'Bills, documents, insurance and licenses at a glance.',
        developer      = 'City Hall',
    },

    notify = {
        billIssued = true, billPaid = true, licenseEarned = true,
        documentOrdered = true, insurancePurchased = true, businessRegistered = true,
        businessPending = true, businessApproved = true, businessRejected = true,   -- Government Portal
        businessSuspended = true, licenseRevoked = true, permitPending = true, permitApproved = true,
        permitRejected = true, permitRevoked = true, employeeAdded = true, businessInspected = true,
    },

    mail = { billIssued = true, sender = 'City Hall' },

    texts = { … },                    -- every notification and mail text
```

## Mail app on the PC

An Outlook-style Mail app on the City Hall PC, with folders, a message list and a reading pane, showing the same mails as the phone. It only appears while a supported phone is running.

| | sd-phone | LB Phone | 17Movement Phone |
| - | - | - | - |
| Read | ✓ inbox, sent, bin | ✓ inbox, sent | ✓ inbox, sent, favourites, bin |
| Write, reply | ✓ (from the player's own address) | ✓ (from the player's own address) | — write on the phone |
| Mark as read, delete | — on the phone | ✓ synced with the phone | — |
| New mail appears | instantly | instantly | within 30 seconds |

```lua theme={null}
Config.Phone.mailApp = {
    enabled      = true,
    maxLength    = 4000,   -- characters per mail written on the PC
    sendCooldown = 10,     -- seconds between two mails from one player
    listLimit    = 100,    -- mails loaded per folder
}
```

> [!WARNING]
>
> LB Phone has no export for reading mails, so the PC reads LB Phone's own mail tables (`phone_mail_messages`, `phone_mail_deleted`, `phone_mail_accounts`). Sending always uses LB Phone's `SendMail` export, so recipients get the normal phone notification. If an LB Phone update changes these tables, the PC mailbox may need an update.

sd-phone is read through its own exports (`getMailAccounts`, `getMailbox`, `sendMailFromPlayer`). It has no export to mark mails read or delete them, so that is done on the phone. The other phones have no export to read mails, so the Mail app is hidden for them.

Players need a mail account in their phone's Mail app first. Until then the PC asks them to set one up.

## Texts

All texts live in `Config.Phone.texts`. `%s` placeholders are filled in this order:

| Text | Placeholders |
| - | - |
| `billIssued` | amount, issuer |
| `billPaid` | amount |
| `licenseEarned` | license name |
| `documentOrdered` | document name, days |
| `insurancePurchased` | plate, days |
| `businessRegistered` | business name |
| `businessPending`, `businessApproved` | business name |
| `businessRejected`, `businessSuspended` | business name, reason |
| `licenseRevoked` | license name |
| `permitPending`, `permitApproved` | permit name, business name |
| `permitRejected`, `permitRevoked` | permit name, business name, reason |
| `employeeAdded` | business name |
| `businessInspected` | business name, result |
| `billMailSubject` | issuer |
| `billMailBody` | bill type, amount, issuer, details + due date |

## Notes

* **LB Phone:** the app is installed by default (`defaultApp`). Notifications show under the City Hall app. Mail goes to the address of the equipped phone; players without a mail account get only the notification.
* **17Movement Phone:** the app is pre-installed on new phones and can be found in the store. Notifications use the system app.
* The app is added again automatically when the phone resource restarts, and removed when City Hall stops.
* Every phone call is protected, so a phone update can't break City Hall. Problems are printed to the console as `[aps_cityhall] phone …`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.