# Server Exports

Server exports provide the authoritative developer API.

API version:

```lua
local version = exports.nord_doorlock:GetApiVersion()
```

Current API version returned by the resource:

```text
1
```

## GetApiVersion

```lua
local version = exports.nord_doorlock:GetApiVersion()
```

Returns a number.

## IsReady

```lua
local ready, errorMessage = exports.nord_doorlock:IsReady()
```

Returns:

```text
boolean ready
string|nil errorMessage
```

Use this when another resource starts at the same time as Nord Doorlock.

## GetDoor

```lua
local door = exports.nord_doorlock:GetDoor(id)
```

Returns a copy of the door table or `nil`.

## GetDoors

```lua
local doors = exports.nord_doorlock:GetDoors()
```

Returns an array of copied door definitions sorted by ID.

## GetDoorCount

```lua
local count = exports.nord_doorlock:GetDoorCount()
```

Returns the number of loaded doors.

## GetDoorState

```lua
local locked = exports.nord_doorlock:GetDoorState(id)
```

Returns:

```text
true  = locked
false = unlocked
nil   = door not found
```

## GetDoorByName

Case-insensitive exact match:

```lua
local door = exports.nord_doorlock:GetDoorByName('Mission Row Front')
```

Returns the first matching door or `nil`.

## FindDoorsByName

Case-insensitive partial search:

```lua
local doors = exports.nord_doorlock:FindDoorsByName('mission')
```

Returns an array.

## FindDoorByCoords

```lua
local door, distance = exports.nord_doorlock:FindDoorByCoords(
    vector3(440.0, -998.0, 30.0),
    5.0
)
```

Coordinates can be a `vector3` or a table:

```lua
{ x = 440.0, y = -998.0, z = 30.0 }
```

Returns the nearest door within the radius and its distance.

## GetNearestDoor

Server-side nearest door for a player:

```lua
local door, distance =
    exports.nord_doorlock:GetNearestDoor(source, 10.0)
```

Requires a valid player source.

## HasAccess

```lua
local allowed = exports.nord_doorlock:HasAccess(source, doorId)
```

Returns `true` or `false`.

This includes the normal Nord Doorlock access rules and registered authorization hooks.

## SetDoorState

```lua
local ok, stateOrError =
    exports.nord_doorlock:SetDoorState(1, true)
```

`true` means locked.

On success:

```text
ok = true
stateOrError = true/false final state
```

On failure:

```text
ok = false
stateOrError = error code
```

## LockDoor

```lua
local ok, result = exports.nord_doorlock:LockDoor(1)
```

## UnlockDoor

```lua
local ok, result = exports.nord_doorlock:UnlockDoor(1)
```

When the door has `autoLock > 0`, unlocking through the API schedules automatic relocking.

## ToggleDoorState

```lua
local ok, result = exports.nord_doorlock:ToggleDoorState(1)
```

## CreateDoor

```lua
local ok, doorOrError, duplicateId =
    exports.nord_doorlock:CreateDoor({
        name = 'Police Front Door',
        distance = 2.0,
        autoLock = 0,
        defaultLocked = true,
        locked = true,

        parts = {
            {
                model = 123456789,
                coords = {
                    x = 440.0,
                    y = -998.0,
                    z = 30.0
                },
                heading = 90.0
            }
        },

        access = {
            jobs = {
                police = 0
            },
            identifiers = {},
            ace = {}
        },

        lockpick = {
            enabled = false
        }
    })
```

On success:

```text
ok = true
doorOrError = created door
```

Potential errors include:

```text
storage_not_ready
invalid_payload
invalid_parts
invalid_part
invalid_part_values
physical_door_already_registered
persistence_failed
```

When the physical door is already registered, the third return value can contain the conflicting door ID.

## UpdateDoor

Patch an existing door:

```lua
local ok, doorOrError, duplicateId =
    exports.nord_doorlock:UpdateDoor(1, {
        autoLock = 30,

        access = {
            jobs = {
                police = 2
            },
            identifiers = {},
            ace = {}
        }
    })
```

Fields not included in the patch are copied from the existing definition.

The `id` is supplied separately and is not overwritten by the patch.

## DeleteDoor

```lua
local ok, errorMessage =
    exports.nord_doorlock:DeleteDoor(1)
```

On success, the door is removed from persistence and clients receive a full synchronization.

## ReloadDoors

```lua
local ok, countOrError, removedDuplicates =
    exports.nord_doorlock:ReloadDoors()
```

On success:

```text
ok = true
countOrError = current door count
removedDuplicates = number removed during reload
```

## GetStorageHealth

```lua
local health = exports.nord_doorlock:GetStorageHealth()
```

See the **Storage & Persistence** page.

## RegisterHook

```lua
local hookId, errorMessage =
    exports.nord_doorlock:RegisterHook(
        'doorAuthorization',
        function(payload)
            return nil
        end,
        {}
    )
```

See the **Authorization Hooks** page.

## RemoveHooks

Remove one hook owned by the calling resource:

```lua
local ok = exports.nord_doorlock:RemoveHooks(hookId)
```

Remove all hooks owned by the calling resource:

```lua
local ok = exports.nord_doorlock:RemoveHooks()
```

## Compatibility Aliases

Lowercase compatibility aliases also exist:

```lua
exports.nord_doorlock:registerHook(...)
exports.nord_doorlock:removeHooks(...)
```

For new integrations, prefer:

```text
RegisterHook
RemoveHooks
```
