# Using ox_target with ESX Legacy (/docs/guides/ox-target)

**`ox_target` works with ESX Legacy**. It provides a third-eye interaction interface for NPCs, vehicles, objects and zones. The maintained `ox_target` source includes an ESX bridge, so its `groups` filter can use ESX job names and minimum grades.

## Installation and resource order [#installation-and-resource-order]

Install the maintained `ox_lib` and `ox_target` releases, then ensure they start before your script. Keep the ESX core and database dependencies configured as described in [Install ESX](/docs/getting-started/installation).

```bash title="server.cfg"
ensure oxmysql
ensure ox_lib
ensure esx_lib
ensure es_extended
ensure ox_target
ensure my_delivery
```

For a resource using both ESX server APIs and ox_target client exports:

```lua title="fxmanifest.lua"
fx_version 'cerulean'
game 'gta5'

shared_script '@es_extended/imports.lua'
client_script 'client.lua'
server_script 'server.lua'
dependencies { 'es_extended', 'ox_target' }
```

The `ox_target` resource depends on `ox_lib`; do not confuse `ox_lib` with ESX's own `esx_lib`.

## Example — create a job-restricted target zone [#example--create-a-job-restricted-target-zone]

This **client** example creates a police-only pickup interaction near a station. Replace the coordinates with your own locations.

```lua title="client.lua"
exports.ox_target:addBoxZone({
    name = 'police_supply_counter',
    coords = vec3(441.0, -981.0, 30.7),
    size = vec3(1.5, 1.2, 1.5),
    rotation = 0,
    debug = false,
    options = {
        {
            name = 'police_collect_supply',
            icon = 'fa-solid fa-box',
            label = 'Collect supplies',
            groups = { police = 0 },
            distance = 2.0,
            serverEvent = 'my_delivery:collectSupply',
        },
    },
})
```

The `groups` setting filters visible options in the client UI. It does **not** authorize the server action.

## Validate the interaction on the server [#validate-the-interaction-on-the-server]

A malicious client can send a server event without using the target interface. Verify the player, job, distance, item capacity and any cooldowns on the server. Never accept a client-submitted item name, price or quantity.

```lua title="server.lua"
local counter = vector3(441.0, -981.0, 30.7)

RegisterNetEvent('my_delivery:collectSupply', function()
    local playerId = source
    local xPlayer = ESX.GetPlayerFromId(playerId)
    if not xPlayer or xPlayer.getJob().name ~= 'police' then return end

    local ped = GetPlayerPed(playerId)
    if ped == 0 then return end
    if #(GetEntityCoords(ped) - counter) > 3.0 then return end

    -- Add an application-specific cooldown and stock check here.
    -- Only grant a configured item that exists in your inventory.
    if xPlayer.canCarryItem('water', 1) then
        xPlayer.addInventoryItem('water', 1)
    end
end)
```

This demonstration checks job and distance but intentionally leaves out production cooldown and stock management. Implement those before using it in a live economy.

## Common ox_target exports [#common-ox_target-exports]

| Client API | Use |
| --- | --- |
| `addBoxZone` / `addSphereZone` | Interact with a 3D area |
| `addModel` | Interact with all objects or vehicles of a model |
| `addLocalEntity` | Interact with a local entity handle |
| `addEntity` | Interact with a network ID |
| `addGlobalVehicle` | Add an option to all vehicles |
| `removeZone` / `removeModel` | Clean up interactions when they are no longer needed |

Options support `groups`, `items`, `canInteract`, `onSelect`, `event` and `serverEvent`. For exact parameter types, use the [official ox_target client API](https://github.com/communityox/docs/blob/main/pages/ox_target/Functions/Client.mdx) and [TargetOptions reference](https://github.com/communityox/docs/blob/main/pages/ox_target/TargetOptions.mdx).

## Troubleshooting [#troubleshooting]

- **No such export `addBoxZone`:** check the resource folder name and startup order.
- **Target never appears:** temporarily set `debug = true`, verify coordinates and confirm ox_target is running.
- **Police-only option never shows:** verify the player's ESX job and grade, then test without `groups` to isolate the filter.
- **Server event fires but no item appears:** inspect server-side permission, distance and inventory checks.
- **Old `qtarget` script:** the compatibility layer is limited; use native ox_target exports for new scripts.

## Related [#related]

- [ESX job creation](/docs/guides/create-a-job)
- [ox_inventory with ESX](/docs/guides/ox-inventory)
- [ESX callbacks](/docs/guides/callbacks)
- [ox_lib with ESX](/docs/guides/ox-lib)
