LonexOne

Developers API reference

API reference

Every v1 endpoint, with parameters and example responses.

All addresses start with https://api.lonexone.com/v1. Send your key as Authorization: Bearer lxk_…; each endpoint says which permission it needs. See Authentication for errors, limits and paging.

Community

Your community, its members, departments, rosters and fleet, news and events. Reading needs community.read; changing rosters needs roster.write.

GET /community community.read

The community the key belongs to, its modules, and what the key can do. A good first call to check a key works.

Request curl
curl https://api.lonexone.com/v1/community \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 12,
        "name": "Sunnyside RP",
        "slug": "sunnyside",
        "url": "https://sunnyside.lonexone.com",
        "modules": [
            "community",
            "departments",
            "cad"
        ],
        "key": {
            "name": "Discord bot",
            "scopes": [
                "community.read",
                "cad.read"
            ]
        }
    }
}
GET /members community.read

Everyone in the community, with their community role, badge number and department places. Paged.

Query parameters
searchstringPart of a username or display name.
discord_idstringOnly this Discord account.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/members \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 7,
            "discord_id": "123456789012345678",
            "username": "ann",
            "name": "Ann Cole",
            "avatar_url": "https://cdn.discordapp.com/…",
            "role": "member",
            "badge_number": "1042",
            "joined_at": "2026-11-02T18:20:00+00:00",
            "departments": [
                {
                    "department_id": 3,
                    "short_name": "LSPD",
                    "rank": "Sergeant",
                    "callsign": "1A-12",
                    "roleplay_name": "Ann Cole",
                    "status": "active"
                }
            ]
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /members/{discord_id} community.read

One member by their Discord id. 404 when they are not in the community.

Request curl
curl https://api.lonexone.com/v1/members/{discord_id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 7,
        "discord_id": "123456789012345678",
        "name": "Ann Cole",
        "role": "member",
        "departments": [
            "…"
        ]
    }
}
GET /departments community.read

Every department with its ranks, highest first, and how many active members it has.

Request curl
curl https://api.lonexone.com/v1/departments \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 3,
            "name": "Los Santos Police Department",
            "short_name": "LSPD",
            "slug": "lspd",
            "type": "police",
            "color": "#3b82f6",
            "member_count": 42,
            "ranks": [
                {
                    "id": 9,
                    "name": "Chief of Police",
                    "abbreviation": "COP",
                    "level": 12
                }
            ]
        }
    ]
}
GET /departments/{id} community.read

One department, with its ranks.

Request curl
curl https://api.lonexone.com/v1/departments/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 3,
        "name": "Los Santos Police Department",
        "short_name": "LSPD",
        "ranks": [
            "…"
        ]
    }
}
GET /departments/{id}/roster community.read

The department roster, highest rank first. People who have left are not included unless you ask for that status.

Query parameters
statusstringactive, training, loa, suspended, inactive or left.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/departments/{id}/roster \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 88,
            "user": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "rank": {
                "id": 5,
                "name": "Sergeant",
                "abbreviation": "Sgt",
                "level": 4
            },
            "callsign": "1A-12",
            "roleplay_name": "Ann Cole",
            "status": "active",
            "joined_at": "2026-10-01T12:00:00+00:00",
            "rank_since": "2026-11-01T09:30:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
POST /departments/{id}/roster roster.write

Puts a community member on the department roster, just as adding them in the panel does: their history, the activity log and Discord roles follow. Someone who left before is welcomed back with their history. Returns 201, or 200 when they rejoin.

Body
discord_idstring, requiredWho to add. They must be in the community.
rank_idintegerA rank in this department.
callsignstringLeft out, departments whose callsigns follow rank pick one.
roleplay_namestringTheir name in roleplay.
Request curl
curl -X POST https://api.lonexone.com/v1/departments/{id}/roster \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"discord_id":"223456789012345678","rank_id":9,"callsign":"1A-20"}'
Response 201 JSON
{
    "data": {
        "id": 89,
        "user": {
            "id": 19,
            "discord_id": "223456789012345678",
            "name": "Ben Park"
        },
        "rank": {
            "id": 9,
            "name": "Officer",
            "abbreviation": "Ofc",
            "level": 1
        },
        "callsign": "1A-20",
        "roleplay_name": null,
        "status": "active",
        "joined_at": "2026-11-09T18:00:00+00:00",
        "rank_since": "2026-11-09T18:00:00+00:00"
    }
}
PATCH /departments/{id}/roster/{discord_id} roster.write

Promotes or demotes someone, changes their callsign or roleplay name, or sets their status. Only what you send changes. Send callsign as null to clear it.

Body
rank_idintegerA rank in this department.
callsignstringMust be free in the department.
roleplay_namestringTheir name in roleplay.
statusstringactive, training, loa, suspended or inactive.
reasonstringShown in their roster history.
Request curl
curl -X PATCH https://api.lonexone.com/v1/departments/{id}/roster/{discord_id} \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"rank_id":10,"reason":"Passed the sergeant exam"}'
Response 200 JSON
{
    "data": {
        "id": 89,
        "rank": {
            "id": 10,
            "name": "Sergeant",
            "abbreviation": "Sgt",
            "level": 2
        },
        "callsign": "2B-04",
        "status": "active"
    }
}
DELETE /departments/{id}/roster/{discord_id} roster.write

Takes someone off the roster and frees their callsign. Their history is kept.

Body
reasonstringShown in their roster history.
Request curl
curl -X DELETE https://api.lonexone.com/v1/departments/{id}/roster/{discord_id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 89,
        "callsign": null,
        "status": "left"
    }
}
GET /fleet/vehicles community.read

Department vehicles and who each one is assigned to.

Query parameters
department_idintegerOnly this department.
discord_idstringOnly vehicles assigned to this person.
platestringSpaces are ignored.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/fleet/vehicles \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 12,
            "name": "Unit 1A-12",
            "model": "Police Cruiser",
            "spawn_code": "police",
            "plate": "LSPD 12",
            "status": "assigned",
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "division": "Patrol",
            "assigned_to": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole",
                "callsign": "1A-12"
            },
            "assigned_at": "2026-11-01T12:00:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /news community.read

Published news posts, pinned first then newest. Follow url to read the whole post on your site.

Query parameters
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/news \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 4,
            "title": "Server update 2.1",
            "excerpt": "New cars and a bigger map.",
            "category": "Updates",
            "pinned": false,
            "visibility": "public",
            "url": "https://sunnyside.lonexone.com/news/server-update-2-1",
            "published_at": "2026-11-07T19:00:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /events community.read

Published events, soonest first. Upcoming by default.

Query parameters
whenstringupcoming, past or all. Default upcoming.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/events \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 2,
            "title": "Sunday car meet",
            "category": "Social",
            "location": "Postal 8012",
            "starts_at": "2026-11-09T19:00:00+00:00",
            "ends_at": "2026-11-09T21:00:00+00:00",
            "cancelled": false,
            "visibility": "public",
            "rsvp_enabled": true,
            "rsvp_count": 14,
            "capacity": 30,
            "url": "https://sunnyside.lonexone.com/events/sunday-car-meet"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}

CAD

Civilian records, vehicles, calls, units, BOLOs and warrants. Reading needs cad.read, creating needs cad.write, and the community needs the CAD module.

GET /cad/characters cad.read

Civilian characters. "John" matches a first or last name; "John Doe" matches both.

Query parameters
searchstringA name, at least 2 characters.
discord_idstringOnly characters this person owns.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/characters \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 31,
            "owner": {
                "id": 7,
                "discord_id": "123456789012345678"
            },
            "first_name": "John",
            "last_name": "Doe",
            "name": "John Doe",
            "date_of_birth": "1990-04-15",
            "gender": "Male",
            "address": "12 Grove St",
            "deceased": false,
            "flags": [
                {
                    "key": "armed",
                    "name": "Armed & dangerous",
                    "severity": "danger"
                }
            ]
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /cad/characters/{id} cad.read

One character in full: licences, vehicles, firearms, and warrants that are pending or active.

Request curl
curl https://api.lonexone.com/v1/cad/characters/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 31,
        "name": "John Doe",
        "licences": [
            {
                "type": "driver",
                "name": "Driver licence",
                "status": "valid",
                "expires_on": "2030-01-01"
            }
        ],
        "vehicles": [
            {
                "id": 50,
                "plate": "ABC 123",
                "make": "Karin",
                "model": "Sultan"
            }
        ],
        "firearms": [
            {
                "id": 8,
                "type": "Pistol",
                "serial": "SN-4471",
                "stolen": false
            }
        ],
        "warrants": [
            {
                "id": 3,
                "number": "WR-0003",
                "status": "active"
            }
        ]
    }
}
GET /cad/vehicles cad.read

Registered vehicles. Plates match without spaces and in any case, so abc123 finds "ABC 123".

Query parameters
platestringA plate.
vinstringA VIN.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/vehicles \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 50,
            "plate": "ABC 123",
            "vin": "1HGCM82633A004352",
            "make": "Karin",
            "model": "Sultan",
            "year": 2019,
            "colour": "Black",
            "registration": "valid",
            "insurance": "valid",
            "stolen": false,
            "impounded": false,
            "flags": [],
            "owner": {
                "id": 31,
                "name": "John Doe"
            }
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /cad/vehicles/{id} cad.read

One vehicle and its owner.

Request curl
curl https://api.lonexone.com/v1/cad/vehicles/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 50,
        "plate": "ABC 123",
        "registration": "valid",
        "owner": {
            "id": 31,
            "name": "John Doe"
        }
    }
}
GET /cad/calls cad.read

Calls with the units on them, newest first. Open calls by default.

Query parameters
statusstringopen, closed or all. Default open.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/calls \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 210,
            "number": 57,
            "nature": "Shots fired",
            "priority": 1,
            "status": "dispatched",
            "source": "911",
            "caller": "Jane",
            "location": "Grove St",
            "postal": "8012",
            "coords": {
                "x": 100,
                "y": -200,
                "z": 30
            },
            "units": [
                {
                    "id": 14,
                    "callsign": "1A-12",
                    "kind": "leo",
                    "status": {
                        "code": "10-97",
                        "label": "En route",
                        "meaning": "enroute"
                    }
                }
            ],
            "created_at": "2026-11-08T20:01:00+00:00",
            "closed_at": null
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /cad/calls/{id} cad.read

One call and its units.

Request curl
curl https://api.lonexone.com/v1/cad/calls/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 210,
        "number": 57,
        "nature": "Shots fired",
        "status": "dispatched",
        "units": [
            "…"
        ]
    }
}
POST /cad/calls cad.write

Puts a new call into dispatch, as if it had been phoned in. The call log shows it came from your key. Returns 201.

Body
naturestring, requiredWhat the call is, up to 80 characters.
descriptionstringDetails, up to 2000 characters.
priorityinteger1 (most urgent) to 4. Default 2.
callerstringWho called.
locationstringStreet or place.
postalstringPostal code. Worked out from coords when left out.
coordsobject{"x": 100, "y": -200, "z": 30} in game coordinates.
Request curl
curl -X POST https://api.lonexone.com/v1/cad/calls \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"nature":"Shots fired","priority":1,"location":"Grove St","coords":{"x":100,"y":-200}}'
Response 201 JSON
{
    "data": {
        "id": 211,
        "number": 58,
        "nature": "Shots fired",
        "priority": 1,
        "status": "pending",
        "source": "api",
        "location": "Grove St",
        "postal": "8012"
    }
}
POST /cad/calls/{id}/notes cad.write

Adds a note to a call's log, shown to dispatch and the units on it as coming from your key. Returns 201.

Body
bodystring, requiredThe note, up to 1000 characters.
Request curl
curl -X POST https://api.lonexone.com/v1/cad/calls/{id}/notes \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"body":"Caller reports two suspects heading north on foot."}'
Response 201 JSON
{
    "data": {
        "id": 905,
        "call_id": 211,
        "body": "Caller reports two suspects heading north on foot.",
        "created_at": "2026-11-08T20:04:00+00:00"
    }
}
POST /cad/calls/{id}/close cad.write

Closes a call and clears the units on it. Closing a call that is already closed changes nothing.

Body
dispositionstringHow it ended, up to 80 characters, like "Report taken".
Request curl
curl -X POST https://api.lonexone.com/v1/cad/calls/{id}/close \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"disposition":"Report taken"}'
Response 200 JSON
{
    "data": {
        "id": 211,
        "number": 58,
        "status": "closed",
        "disposition": "Report taken",
        "closed_at": "2026-11-08T20:40:00+00:00",
        "units": []
    }
}
GET /cad/units cad.read

Every unit on duty now, with status, department and the call they are on. Not paged.

Request curl
curl https://api.lonexone.com/v1/cad/units \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 14,
            "callsign": "1A-12",
            "kind": "leo",
            "status": {
                "code": "10-8",
                "label": "Available",
                "meaning": "available"
            },
            "person": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "call_id": null,
            "on_duty_since": "2026-11-08T19:00:00+00:00"
        }
    ]
}
GET /cad/bolos cad.read

BOLOs, newest first. Active ones by default.

Query parameters
statusstringactive or all. Default active.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/bolos \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 6,
            "kind": "vehicle",
            "threat": "armed",
            "title": "Robbery getaway car",
            "description": "Black Sultan, two occupants",
            "plate": "XYZ 9",
            "location": "Route 68",
            "active": true,
            "expires_at": null,
            "cleared_at": null,
            "created_at": "2026-11-08T20:10:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
POST /cad/bolos cad.write

Issues a BOLO. Returns 201.

Body
kindstring, requiredperson, vehicle or both.
titlestring, requiredUp to 120 characters.
threatstringarmed, flight or low. Default low.
descriptionstringUp to 2000 characters.
platestringUp to 8 characters.
locationstringLast seen.
expires_in_hoursinteger1 to 8760. Leave out to keep it until cleared.
Request curl
curl -X POST https://api.lonexone.com/v1/cad/bolos \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"kind":"vehicle","title":"Robbery getaway car","threat":"armed","plate":"XYZ 9","expires_in_hours":4}'
Response 201 JSON
{
    "data": {
        "id": 7,
        "kind": "vehicle",
        "threat": "armed",
        "title": "Robbery getaway car",
        "plate": "XYZ 9",
        "active": true,
        "expires_at": "2026-11-09T00:10:00+00:00"
    }
}
POST /cad/bolos/{id}/clear cad.write

Clears a BOLO so it stops showing as active. Clearing one already cleared changes nothing.

Request curl
curl -X POST https://api.lonexone.com/v1/cad/bolos/{id}/clear \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 7,
        "title": "Robbery getaway car",
        "active": false,
        "cleared_at": "2026-11-08T21:00:00+00:00"
    }
}
GET /cad/warrants cad.read

Warrants, newest first. Active ones by default.

Query parameters
statusstringpending, active, served, cancelled, denied or all. Default active.
character_idintegerOnly this character.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/warrants \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 3,
            "number": "WR-0003",
            "type": "arrest",
            "status": "active",
            "subject": {
                "character_id": 31,
                "name": "John Doe"
            },
            "charges": [
                {
                    "code": "PC 211",
                    "name": "Robbery",
                    "type": "felony"
                }
            ],
            "reason": "Seen on camera",
            "officer": {
                "name": "Ann Cole",
                "callsign": "1A-12"
            },
            "department_id": 3,
            "created_at": "2026-11-08T18:00:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /cad/plate-reads cad.read

Players' plates read by the plate reader in police cars, newest first. Kept for as many days as your CAD settings say.

Query parameters
platestringSpaces are ignored.
sincedateRead on or after this date.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/plate-reads \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 9001,
            "plate": "ABC123",
            "model": "Sultan",
            "speed": 74,
            "reader": "front",
            "unit": {
                "id": 14,
                "callsign": "1A-12"
            },
            "postal": "8012",
            "location": "Route 68",
            "coords": {
                "x": 1204.5,
                "y": 2680.1
            },
            "read_at": "2026-11-08T21:14:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /cad/charges cad.read

Every charge in the community's penal code, with its fine, jail time and points. Use the ids to write a record. Not paged.

Request curl
curl https://api.lonexone.com/v1/cad/charges \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 41,
            "category": "Traffic",
            "code": "VC 22350",
            "name": "Speeding",
            "type": "infraction",
            "fine": 250,
            "jail_months": 0,
            "points": 2
        }
    ]
}
GET /cad/records cad.read

Citations, written warnings and arrests on file, newest first. Records waiting for approval or expunged are left out unless you ask for them. The narrative is only in the single record.

Query parameters
typestringcitation, warning or arrest.
statusstringfiled, pending, returned, expunged or all. Default filed.
character_idintegerOnly this character.
department_idintegerOnly this department.
sincedateWritten on or after this date.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/cad/records \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 210,
            "reference": "C-0042",
            "type": "citation",
            "status": "filed",
            "expunged": false,
            "subject": {
                "character_id": 31,
                "name": "John Doe"
            },
            "officer": {
                "name": "Ann Cole",
                "callsign": "1A-12"
            },
            "department_id": 3,
            "call_id": null,
            "charges": [
                {
                    "code": "VC 22350",
                    "name": "Speeding",
                    "type": "infraction",
                    "fine": 250,
                    "jail_months": 0,
                    "points": 2
                }
            ],
            "total_fine": 250,
            "total_jail_months": 0,
            "total_points": 2,
            "fine_paid": 250,
            "location": "Route 68",
            "postal": "8012",
            "plate": "ABC 123",
            "served_at": "2026-11-08T21:05:00+00:00",
            "occurred_at": "2026-11-08T21:00:00+00:00",
            "created_at": "2026-11-08T21:02:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /cad/records/{id} cad.read

One citation, warning or arrest, with the officer's narrative in notes.

Request curl
curl https://api.lonexone.com/v1/cad/records/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 211,
        "reference": "A-0107",
        "type": "arrest",
        "status": "filed",
        "subject": {
            "character_id": 31,
            "name": "John Doe"
        },
        "total_jail_months": 24,
        "notes": "Stopped the vehicle on Route 68…"
    }
}
POST /cad/records cad.write

Writes a record as an officer who is on duty in the CAD, just as if they filed it themselves: numbering, supervisor approval, licence points, fines in game and Discord logs all follow your settings. Returns 201.

Body
typestring, requiredcitation, warning or arrest.
officer_discord_idstring, requiredThe officer writing it. They must be on duty in the CAD.
character_idinteger, requiredWho it is for.
chargesarray of integersCharge ids from the penal code. Needed for citations and arrests.
notesstringThe narrative. Needed for arrests.
locationstringWhere it happened.
postalstringThe postal.
platestringThe vehicle's plate.
call_idintegerThe call it belongs to.
Request curl
curl -X POST https://api.lonexone.com/v1/cad/records \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"type":"citation","officer_discord_id":"123456789012345678","character_id":31,"charges":[41],"location":"Route 68","plate":"ABC 123"}'
Response 201 JSON
{
    "data": {
        "id": 212,
        "reference": "C-0043",
        "type": "citation",
        "status": "filed",
        "total_fine": 250
    }
}

Staff Panel and store

Staff, players, bans and warnings need staff.read and the Staff Panel module; giving and revoking them needs staff.write. IP addresses, hardware tokens and staff notes are never sent. Store payments need store.read.

GET /staff/on-duty staff.read

Staff on duty now, highest rank first. Not paged.

Request curl
curl https://api.lonexone.com/v1/staff/on-duty \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "user": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "since": "2026-11-08T19:00:00+00:00",
            "seconds": 5400
        }
    ]
}
GET /staff/ban-check staff.read

Whether someone is banned now. Send any of their identifiers. A ban counts on their license or Discord, and on other identifiers when your Staff Panel bans linked accounts. Bans for one server only are left out.

Query parameters
licensestringRockstar license, with or without "license:".
discordstringDiscord id.
steamstringSteam hex.
fivemstringCfx.re account id.
license2, xbl, livestringOther identifiers.
Request curl
curl https://api.lonexone.com/v1/staff/ban-check \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "banned": true,
        "ban": {
            "id": 55,
            "reference": "B-0019",
            "type": "ban",
            "label": "Ban · 7 days",
            "status": "active",
            "reason": "RDM",
            "rule": {
                "code": "3.1",
                "title": "No random deathmatch"
            },
            "minutes": 10080,
            "expires_at": "2026-11-15T20:00:00+00:00",
            "issued_by": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "player": {
                "id": 120,
                "name": "Speedy"
            }
        }
    }
}
GET /staff/players staff.read

Players seen on your game servers, most recently seen first. Find someone by any identifier or by a name they have used.

Query parameters
license, discord, steam, fivemstringAny identifier.
searchstringA name they have played under.
onlinebooleanOnly players in game now.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/staff/players \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 120,
            "name": "Speedy",
            "member": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "identifiers": [
                {
                    "kind": "license",
                    "value": "3f9a…"
                },
                {
                    "kind": "discord",
                    "value": "123456789012345678"
                }
            ],
            "online": true,
            "playtime_seconds": 318000,
            "trust_score": 72,
            "active_actions": 1,
            "first_seen_at": "2026-10-02T18:00:00+00:00",
            "last_seen_at": "2026-11-08T22:10:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /staff/players/{id} staff.read

One player with every warning, kick, ban, commendation and community service against them, newest first.

Request curl
curl https://api.lonexone.com/v1/staff/players/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 120,
        "name": "Speedy",
        "online": false,
        "actions": [
            {
                "id": 55,
                "type": "ban",
                "label": "Ban · 7 days",
                "status": "active",
                "reason": "RDM",
                "created_at": "2026-11-08T20:00:00+00:00"
            }
        ]
    }
}
POST /staff/actions staff.write

Gives a warning, kick, ban, commendation or community service as one of your staff, with their permissions. Their temp-ban limit, immunity, rank, rule guidelines and approval of long bans all apply as in the panel, and a player in game is kicked or warned straight away. Returns 201.

Body
staff_discord_idstring, requiredThe staff member giving it.
player_idinteger, requiredFrom List players.
typestring, requiredwarn, kick, ban, commend or service.
reasonstring, requiredUp to 500 characters.
minutesintegerBan length. Leave out for a permanent ban.
rule_idintegerThe rule broken.
guideline_reasonstringWhy, when going against the rule's guideline.
tasksintegerCommunity service tasks, 1 to 100.
server_onlybooleanA ban for one server only.
server_idintegerThat server.
Request curl
curl -X POST https://api.lonexone.com/v1/staff/actions \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"staff_discord_id":"123456789012345678","player_id":120,"type":"ban","reason":"RDM","minutes":10080}'
Response 201 JSON
{
    "data": {
        "id": 55,
        "reference": "B7KQ2M",
        "type": "ban",
        "label": "Ban · 7 days",
        "status": "active",
        "reason": "RDM",
        "minutes": 10080,
        "expires_at": "2026-11-16T20:00:00+00:00",
        "source": "api"
    }
}
POST /staff/actions/{id}/revoke staff.write

Lifts a ban, or takes back a warning, kick or commendation so it stops counting. The staff member needs the Manage staff actions permission.

Body
staff_discord_idstring, requiredThe staff member doing it.
reasonstring, requiredUp to 500 characters.
Request curl
curl -X POST https://api.lonexone.com/v1/staff/actions/{id}/revoke \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"staff_discord_id":"123456789012345678","reason":"Appeal accepted"}'
Response 200 JSON
{
    "data": {
        "id": 55,
        "type": "ban",
        "status": "revoked",
        "revoked_at": "2026-11-10T09:00:00+00:00"
    }
}
GET /staff/actions staff.read

Warnings, kicks, bans, commendations and community service across every player, newest first. Active ones by default.

Query parameters
typestringcommend, warn, kick, service or ban.
statusstringactive, pending, denied, revoked or all. Default active.
player_idintegerOnly this player.
staff_discord_idstringOnly ones this staff member gave.
sincedateGiven on or after this date.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/staff/actions \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 55,
            "reference": "B-0019",
            "type": "ban",
            "label": "Ban · 7 days",
            "status": "active",
            "reason": "RDM",
            "minutes": 10080,
            "expires_at": "2026-11-15T20:00:00+00:00",
            "server_only": false,
            "tasks": null,
            "issued_by": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "source": "panel",
            "player": {
                "id": 120,
                "name": "Speedy"
            },
            "created_at": "2026-11-08T20:00:00+00:00",
            "revoked_at": null
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /store/payments store.read

Store payments recorded from Tebex, newest first. Filter by Discord id to see what someone bought.

Query parameters
discord_idstringOnly this buyer.
statusstringcomplete, refunded or chargeback.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/store/payments \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 90,
            "transaction_id": "tbx-26a1c3",
            "status": "complete",
            "buyer": {
                "name": "player",
                "discord_id": "123456789012345678",
                "fivem_id": null
            },
            "amount": "9.99",
            "currency": "USD",
            "packages": [
                {
                    "id": 12,
                    "name": "VIP",
                    "quantity": 1
                }
            ],
            "paid_at": "2026-11-08T14:31:09+00:00",
            "refunded_at": null
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}

Shifts and applications

Department shifts and hours need shifts.read. Applications need applications.read, and deciding them needs applications.write. Reviewer notes are never sent.

GET /shifts/hours shifts.read

Time on duty per person and department, most hours first. Shifts count in the period they started in. The last 30 days by default, and a year at most. Not paged.

Query parameters
sincedateFrom this date. Default 30 days ago.
untildateUp to this date. Default now.
department_idintegerOnly this department.
discord_idstringOnly this person.
Request curl
curl https://api.lonexone.com/v1/shifts/hours \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "member": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole",
                "callsign": "1A-12",
                "roleplay_name": "Ann Cole"
            },
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "shifts": 12,
            "seconds": 129600,
            "hours": 36
        }
    ],
    "meta": {
        "since": "2026-10-09T00:00:00+00:00",
        "until": "2026-11-08T00:00:00+00:00"
    }
}
GET /shifts shifts.read

Shifts, newest first, with how long each lasted not counting breaks.

Query parameters
openbooleantrue for shifts going on now, false for finished ones.
department_idintegerOnly this department.
discord_idstringOnly this person.
sincedateStarted on or after this date.
untildateStarted before this date.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/shifts \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 501,
            "member": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole",
                "callsign": "1A-12",
                "roleplay_name": "Ann Cole"
            },
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "started_at": "2026-11-08T19:00:00+00:00",
            "ended_at": "2026-11-08T22:00:00+00:00",
            "paused": false,
            "seconds": 10800,
            "source": "cad",
            "auto_closed": false
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /applications applications.read

Applications to your forms, newest first. Open ones (pending or interview) by default.

Query parameters
statusstringopen, pending, interview, accepted, denied, withdrawn or all. Default open.
form_idintegerOnly this form.
department_idintegerOnly forms for this department.
discord_idstringOnly this applicant.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/applications \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 77,
            "form": {
                "id": 2,
                "title": "LSPD application"
            },
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "applicant": {
                "id": 19,
                "discord_id": "223456789012345678",
                "name": "Ben Park"
            },
            "status": "pending",
            "votes": {
                "approve": 2,
                "deny": 0
            },
            "decided_by": null,
            "decided_at": null,
            "decision_message": null,
            "created_at": "2026-11-08T16:00:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /applications/{id} applications.read

One application, with each question as it was asked and the answer given.

Request curl
curl https://api.lonexone.com/v1/applications/{id} \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 77,
        "status": "pending",
        "answers": [
            {
                "question": "Why do you want to join?",
                "answer": "I enjoy patrol roleplay."
            }
        ]
    }
}
POST /applications/{id}/decision applications.write

Decides an application as the panel does: the applicant is told on Discord, with your message, and accepting puts them on the department roster at the form's starting rank. Only open applications can be decided, and only pending ones sent to interview.

Body
decisionstring, requiredinterview, accept or deny.
messagestringSent to the applicant. Up to 2000 characters.
Request curl
curl -X POST https://api.lonexone.com/v1/applications/{id}/decision \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"decision":"accept","message":"Welcome aboard. Report to Mission Row on Friday."}'
Response 200 JSON
{
    "data": {
        "id": 77,
        "status": "accepted",
        "decided_at": "2026-11-09T18:00:00+00:00",
        "decision_message": "Welcome aboard. Report to Mission Row on Friday.",
        "answers": [
            "…"
        ]
    }
}

Training

Training sessions, test results and certifications need training.read; bookings, enrolments and awarding certifications need training.write. Both need the Training module. Answers and instructor notes are never sent.

GET /training/sessions training.read

Training sessions. Upcoming and live ones by default, soonest first.

Query parameters
statusstringupcoming, scheduled, live, ended, cancelled or all. Default upcoming.
department_idintegerOnly this department.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/training/sessions \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 9,
            "title": "Patrol basics",
            "test": {
                "id": 3,
                "name": "Patrol test"
            },
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "host": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole"
            },
            "status": "scheduled",
            "location": "Mission Row",
            "starts_at": "2026-11-10T19:00:00+00:00",
            "ends_at": "2026-11-10T20:30:00+00:00",
            "capacity": 10,
            "attending": 6,
            "bookings_open": true
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /training/results training.read

Pass and fail results from test sessions, newest first.

Query parameters
discord_idstringOnly this person.
test_idintegerOnly this test.
outcomestringpass or fail.
sincedateDecided on or after this date.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/training/results \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 140,
            "person": {
                "id": 19,
                "discord_id": "223456789012345678",
                "name": "Ben Park"
            },
            "session": {
                "id": 9,
                "title": "Patrol basics"
            },
            "test": {
                "id": 3,
                "name": "Patrol test"
            },
            "outcome": "pass",
            "marks": 18,
            "max_marks": 20,
            "percent": 90,
            "decided_at": "2026-11-10T20:40:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
GET /training/certifications training.read

Certifications people hold now, newest first. Send current=false to include expired and revoked ones.

Query parameters
discord_idstringOnly this person.
certification_idintegerOnly this certification.
currentbooleanDefault true.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/training/certifications \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 61,
            "person": {
                "id": 19,
                "discord_id": "223456789012345678",
                "name": "Ben Park"
            },
            "certification": {
                "id": 4,
                "name": "Firearms",
                "abbreviation": "FA",
                "department_id": 3
            },
            "awarded_at": "2026-11-10T20:45:00+00:00",
            "expires_at": "2027-05-10T20:45:00+00:00",
            "revoked_at": null
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
POST /training/sessions/{id}/bookings training.write

Books someone onto a session, marks them unavailable, or takes them off the list. The same checks as the site apply: bookings open, room left, and in the department the session is for. The session's Discord post updates.

Body
discord_idstring, requiredWho.
attendancestring, requiredattending, unavailable or none.
Request curl
curl -X POST https://api.lonexone.com/v1/training/sessions/{id}/bookings \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"discord_id":"223456789012345678","attendance":"attending"}'
Response 200 JSON
{
    "data": {
        "session_id": 9,
        "person": {
            "id": 19,
            "discord_id": "223456789012345678",
            "name": "Ben Park"
        },
        "attendance": "attending",
        "attending": 7
    }
}
POST /training/enrolments training.write

Starts someone on a certification's training programme, as an instructor does in the panel. Someone who holds it already starts a renewal. Returns 201.

Body
discord_idstring, requiredThe trainee.
certification_idinteger, requiredThe certification whose programme to start.
instructor_discord_idstringTheir instructor.
Request curl
curl -X POST https://api.lonexone.com/v1/training/enrolments \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"discord_id":"223456789012345678","certification_id":4,"instructor_discord_id":"123456789012345678"}'
Response 201 JSON
{
    "data": {
        "id": 33,
        "person": {
            "id": 19,
            "discord_id": "223456789012345678",
            "name": "Ben Park"
        },
        "certification": {
            "id": 4,
            "name": "Firearms"
        },
        "instructor": {
            "id": 7,
            "discord_id": "123456789012345678",
            "name": "Ann Cole"
        },
        "status": "active",
        "renewal": false,
        "started_at": "2026-11-09T18:00:00+00:00"
    }
}
POST /training/certifications training.write

Awards a certification, or renews one that expires. Ones that never expire can only be held once. They are told on the site and Discord, and linked Discord roles follow. Returns 201.

Body
discord_idstring, requiredWho.
certification_idinteger, requiredWhich certification.
Request curl
curl -X POST https://api.lonexone.com/v1/training/certifications \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"discord_id":"223456789012345678","certification_id":4}'
Response 201 JSON
{
    "data": {
        "id": 62,
        "certification": {
            "id": 4,
            "name": "Firearms"
        },
        "awarded_at": "2026-11-09T18:00:00+00:00",
        "expires_at": "2027-05-09T18:00:00+00:00",
        "revoked_at": null
    }
}
POST /training/certifications/{id}/revoke training.write

Takes away a certification someone holds, by the id from List certifications held. Linked Discord roles follow.

Request curl
curl -X POST https://api.lonexone.com/v1/training/certifications/{id}/revoke \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 62,
        "certification": {
            "id": 4,
            "name": "Firearms"
        },
        "revoked_at": "2026-11-09T19:00:00+00:00"
    }
}

Leave of absence

Leave requests need leave.read; asking for, approving, denying and ending leave needs leave.write. The member's roster status changes with their leave, as it does on the site.

GET /leave leave.read

Leave requests, newest first. By default, pending and approved ones that haven't finished.

Query parameters
statusstringopen, current (on leave today), pending, approved, denied, cancelled, ended or all. Default open.
department_idintegerOnly this department.
discord_idstringOnly this person.
per_pageinteger1 to 100. Default 50.
Request curl
curl https://api.lonexone.com/v1/leave \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": [
        {
            "id": 14,
            "member": {
                "id": 7,
                "discord_id": "123456789012345678",
                "name": "Ann Cole",
                "callsign": "1A-12"
            },
            "department": {
                "id": 3,
                "short_name": "LSPD"
            },
            "starts_on": "2026-11-12",
            "ends_on": "2026-11-20",
            "days": 9,
            "reason": "Holiday",
            "status": "approved",
            "on_leave_now": false,
            "reviewed_by": {
                "id": 2,
                "name": "Sam Hale"
            },
            "reviewed_at": "2026-11-09T12:00:00+00:00",
            "review_note": null,
            "created_at": "2026-11-08T20:00:00+00:00"
        }
    ],
    "links": {
        "first": "…?page=1",
        "last": "…?page=3",
        "prev": null,
        "next": "…?page=2"
    },
    "meta": {
        "current_page": 1,
        "per_page": 50,
        "total": 120
    }
}
POST /leave leave.write

Asks for leave for someone, as if they asked on the community site. They must be active in the department, leave is 90 days at most, and it can't overlap leave they already have. Reviewers are told as usual. Returns 201.

Body
discord_idstring, requiredWho.
department_idinteger, requiredTheir department.
starts_ondate, requiredYYYY-MM-DD, today or later.
ends_ondate, requiredYYYY-MM-DD.
reasonstring, requiredUp to 1000 characters.
Request curl
curl -X POST https://api.lonexone.com/v1/leave \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"discord_id":"123456789012345678","department_id":3,"starts_on":"2026-11-12","ends_on":"2026-11-20","reason":"Holiday"}'
Response 201 JSON
{
    "data": {
        "id": 14,
        "starts_on": "2026-11-12",
        "ends_on": "2026-11-20",
        "days": 9,
        "status": "pending"
    }
}
POST /leave/{id}/decision leave.write

Approves or denies a pending request. They are told on the site and Discord. Approved leave that has already started puts them on LOA straight away.

Body
decisionstring, requiredapprove or deny.
notestringSent to them. Up to 1000 characters.
Request curl
curl -X POST https://api.lonexone.com/v1/leave/{id}/decision \
  -H "Authorization: Bearer lxk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"decision":"approve","note":"Enjoy your break"}'
Response 200 JSON
{
    "data": {
        "id": 14,
        "status": "approved",
        "review_note": "Enjoy your break"
    }
}
POST /leave/{id}/end leave.write

Ends leave that has started, today, and gives them back the roster status they had before.

Request curl
curl -X POST https://api.lonexone.com/v1/leave/{id}/end \
  -H "Authorization: Bearer lxk_your_key"
Response 200 JSON
{
    "data": {
        "id": 14,
        "ends_on": "2026-11-15",
        "status": "ended",
        "on_leave_now": false
    }
}