Commands#
Housing Creator registers a few in-game commands, two of them with keybinds players can change in their FiveM settings. Command names that come from the config can be renamed there.
Command | Who | Description |
|---|---|---|
| Owners, tenants, key holders | Opens the management panel of the house you are at. Outside an apartment building it lists your apartments. Key: |
| Admins, real estate jobs | Opens the creator: houses, furniture shops and agencies. Key: |
| Everyone | Opens the house browser. Only when |
| Agency members with boss menu access | Opens the real estate agency boss menu. Name and optional key in |
| Admins, real estate jobs | Standing at a house, evicts its tenant (it stays listed for rent). In an apartment building it lists the rented units. Name: |
| Admins | Opens the furniture creator: add, edit and photograph catalogue items. Name: |
| Everyone | Sends every house to your client again — for when houses or blips did not load on join. |
| Server console | One-time migration for servers coming from a very old version: moves furniture from the old storage format to the current one, then asks for a restart. |
revert_decorationschanges your database. Back it up first, and run it only when moving from an old version. WhileConfig.Debugis on, a few developer commands are registered too; they disappear when it is off.
Client Exports#
For HUDs, radial menus, spawn selectors and anything else that needs to know where the player is.
Where the player is
exports['qs-housing']:getEnteredHouse() -- house the player is inside, or nil
exports['qs-housing']:getCurrentHouse() -- house whose zone the player is in (outside too), or nil
exports['qs-housing']:GetCurrentHouseData() -- access to the current house (below)
exports['qs-housing']:GetCurrentHouseUpgrades() -- upgrades of the current houseGetCurrentHouseData returns haskey, isOwned, isOfficialOwner, rentable, purchasable, houseRented, billsCutOff, lightsOn and more.
local house = exports['qs-housing']:getEnteredHouse()
if house and exports['qs-housing']:GetCurrentHouseData().haskey then
print('At home in', house)
endHouse data
exports['qs-housing']:getHouseData(house) -- one house: coords, price, interior, upgrades...
exports['qs-housing']:getHouseList() -- every house (waits until houses are loaded)
exports['qs-housing']:getShells() -- the shell list from the config (client and server)Entering and leaving
exports['qs-housing']:enterHouse(house, false) -- teleports the player in, without checking keys
exports['qs-housing']:CleanupPlayerHousingState() -- forces the player out of every housing stateCall CleanupPlayerHousingState from a multicharacter or logout script before switching characters.
Interfaces
exports['qs-housing']:OpenPropertyHub(house, houseData, currentHouseData)
exports['qs-housing']:ClosePropertyHub()
exports['qs-housing']:OpenAgencyBossMenu(agencyId)
exports['qs-housing']:inDecorate() -- true while decorate mode is openSecurity cameras
local cams = exports['qs-housing']:GetSecurityCameras() -- { { id = 12 }, ... }
if cams[1] then
exports['qs-housing']:WatchSecurityCamera(cams[1].id)
endShells
Add a shell from another resource without editing the config:
exports['qs-housing']:AddShell({ model = 'my_shell_model', stash = { maxweight = 1000000, slots = 10 } })Server Exports#
How other resources drive Housing Creator. target means a player's server id or their identifier (citizenid on QBCore).
Reading ownership
exports['qs-housing']:GetPlayerHouses(source) -- { 'house_1', ... } owned or rented
exports['qs-housing']:GetPlayerPropertiesByIdentifier(identifier) -- with label, address, coords, image; works offline
exports['qs-housing']:GetHouseOwner(house) -- identifier, 'realestate' or 'agency_<id>'
exports['qs-housing']:GetPlayerInsideHouse(source) -- the house the player is saved inside
exports['qs-housing']:CheckHasKey(identifier, identifier, house, source)
exports['qs-housing']:CanOwnAnotherHouse(identifier) -- under the house limit (VIP slots included)Giving and taking houses
local ok, err = exports['qs-housing']:AssignHouseToPlayer(target, house, { notify = true, skipMaxLimit = false })
-- err: invalid_house, invalid_target, house_not_found, house_already_owned, max_houses_reached
exports['qs-housing']:ClearHouseOwnership(house, { notify = true }) -- back on the market
exports['qs-housing']:ReleaseRenter(house, true) -- evict the tenant, keep it listed
exports['qs-housing']:BankHandover(house, identifier) -- bank deal; nil returns it to market
exports['qs-housing']:deleteHouse(house) -- deletes the house completelyNone of these charge money. AssignHouseToPlayer is the export for rewards, starter homes and admin tools.
Character deletion and stuck players
local ok, summary = exports['qs-housing']:OnCharacterWipe(identifier)
-- summary = { released = {...}, cleared = {...}, transferred = {...} }
exports['qs-housing']:ClearPlayerInsideByIdentifier(identifier) -- player spawns outside next timeOnCharacterWipe ends rentals, clears or hands over owned houses, and removes the character from every key list. Call it from your character-delete script.
Keys
exports['qs-housing']:GiveMetaKey(source, house) -- gives a new physical key item
exports['qs-housing']:RemoveMetaKey(source, house)
exports['qs-housing']:CheckHasMetaKey(source, house)Available while Config.EnableMetaKey is on.
Payments: mortgage, rent and bills
For banking apps and phone apps. Quote first, take the money your own way, then confirm:
local quote = exports['qs-housing']:QuoteHousingPayment(target, house, 'mortgage') -- 'mortgage' | 'rent' | 'bill'
if quote.ok and MyBank.Charge(target, quote.amount) then
exports['qs-housing']:ConfirmHousingPayment(target, house, 'mortgage', { alreadyCollected = true })
end
-- Without alreadyCollected, Housing Creator charges the player itself.
exports['qs-housing']:PayHouseMortgage(target, house, {})
exports['qs-housing']:PayHouseRent(target, house, {})
exports['qs-housing']:PayHouseBill(source, billId)To read everything a player is tied to — owned, rented, keys, mortgage, rent due, unpaid bills:
local result = exports['qs-housing']:GetPlayerHousingContracts(target)
local one = exports['qs-housing']:GetHouseContract(house, target)Config.HousingApps.AllowedResources limits which resources may call these. Empty means any. With SkipAutoChargeOnExternalPay, a payment made this way skips the next automatic charge.
VIP houses
exports['qs-housing']:GrantVipHouse(target, house, { notify = true }) -- free, skips the house limit
exports['qs-housing']:RevokeVipHouse(house)
exports['qs-housing']:SetVipExtraHouseSlots(identifier, 2) -- added to Config.MaxOwnedHouses
exports['qs-housing']:GetVipExtraHouseSlots(identifier)Blocking sales and transfers
Take a house off the market completely — it cannot be bought, rented or mortgaged, and disappears from the browser and map:
exports['qs-housing']:SetHouseForSale(house, false)
exports['qs-housing']:IsHouseForSale(house)Or veto specific player actions with your own rules:
exports['qs-housing']:RegisterHouseTransactionVeto('gang_rules', function(ctx)
-- ctx.action: 'sell_bank', 'list_player_sale', 'buy_from_player' or 'transfer'
if ctx.action == 'transfer' and IsGangHouse(ctx.house) then
return false, 'Gang houses cannot be transferred'
end
return true
end)
exports['qs-housing']:UnregisterHouseTransactionVeto('gang_rules')Furniture
Add items to an existing catalogue category (how the [dlc] packs work), or place furniture in a house:
exports['qs-housing']:AddFurniture('sofa', {
object = 'my_sofa', label = 'My Sofa', price = 1200,
description = 'Comfortable.', img = 'https://example.com/my_sofa.webp',
colorlabel = 'Grey', colors = {},
})
exports['qs-housing']:addDecorationToHouse(house, {
modelName = 'my_sofa',
coords = vec3(0.0, 0.0, 0.0),
rotation = vec3(0.0, 0.0, 0.0),
inStash = true, -- true: goes to the owner's furniture stash
inHouse = false,
})
exports['qs-housing']:addDecorationBatchToHouse(house, { ... })Agencies
exports['qs-housing']:GetAgencyById(id)
exports['qs-housing']:GetAgencyByName(name)
exports['qs-housing']:GetPlayerAgencyMembership(identifier) -- agency, rank and permissions
exports['qs-housing']:CanManageHouse(source, house) -- owner or agency manager
exports['qs-housing']:ResolveAgencyIdForHouse(house)After changing data yourself
exports['qs-housing']:RefreshHouseCache(house, 'bills') -- 'bills', 'house_meta_keys' or 'meta_key_valid'Events#
Server events to listen to with AddEventHandler:
Event | Fires when |
|---|---|
|
|
| A house is created, edited or deleted in the creator. |
|
|
|
|
|
|
Client events:
AddEventHandler('housing:onEnterHouse', function(house) end) -- entered a house interior
AddEventHandler('housing:onExitHouse', function(house) end)
AddEventHandler('housing:handleEnterZone', function(house) end) -- walked into a property zone
AddEventHandler('housing:handleExitZone', function(house) end)
RegisterNetEvent('qs-housing:client:contractUpdated', function(data) end) -- { house, action }Compatibility with qb-houses#
Scripts written for qb-houses keep working: exports['qb-houses']:hasKey(...) is answered by Housing Creator, and spawn selectors can still trigger qb-houses:client:enterOwnedHouse and qb-houses:client:LastLocationHouse. The console reminds you to move those scripts to the qs-housing exports; do not run the real qb-houses alongside.



