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.
/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.
curl https://api.lonexone.com/v1/community \ -H "Authorization: Bearer lxk_your_key"
{
"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"
]
}
}
}
/members
community.read
Everyone in the community, with their community role, badge number and department places. Paged.
searchstring | Part of a username or display name. |
discord_idstring | Only this Discord account. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/members \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/members/{discord_id}
community.read
One member by their Discord id. 404 when they are not in the community.
curl https://api.lonexone.com/v1/members/{discord_id} \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 7,
"discord_id": "123456789012345678",
"name": "Ann Cole",
"role": "member",
"departments": [
"…"
]
}
}
/departments
community.read
Every department with its ranks, highest first, and how many active members it has.
curl https://api.lonexone.com/v1/departments \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
]
}
]
}
/departments/{id}
community.read
One department, with its ranks.
curl https://api.lonexone.com/v1/departments/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 3,
"name": "Los Santos Police Department",
"short_name": "LSPD",
"ranks": [
"…"
]
}
}
/departments/{id}/roster
community.read
The department roster, highest rank first. People who have left are not included unless you ask for that status.
statusstring | active, training, loa, suspended, inactive or left. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/departments/{id}/roster \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/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.
discord_idstring, required | Who to add. They must be in the community. |
rank_idinteger | A rank in this department. |
callsignstring | Left out, departments whose callsigns follow rank pick one. |
roleplay_namestring | Their name in roleplay. |
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"}'
{
"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"
}
}
/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.
rank_idinteger | A rank in this department. |
callsignstring | Must be free in the department. |
roleplay_namestring | Their name in roleplay. |
statusstring | active, training, loa, suspended or inactive. |
reasonstring | Shown in their roster history. |
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"}'
{
"data": {
"id": 89,
"rank": {
"id": 10,
"name": "Sergeant",
"abbreviation": "Sgt",
"level": 2
},
"callsign": "2B-04",
"status": "active"
}
}
/departments/{id}/roster/{discord_id}
roster.write
Takes someone off the roster and frees their callsign. Their history is kept.
reasonstring | Shown in their roster history. |
curl -X DELETE https://api.lonexone.com/v1/departments/{id}/roster/{discord_id} \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 89,
"callsign": null,
"status": "left"
}
}
/fleet/vehicles
community.read
Department vehicles and who each one is assigned to.
department_idinteger | Only this department. |
discord_idstring | Only vehicles assigned to this person. |
platestring | Spaces are ignored. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/fleet/vehicles \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/news
community.read
Published news posts, pinned first then newest. Follow url to read the whole post on your site.
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/news \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/events
community.read
Published events, soonest first. Upcoming by default.
whenstring | upcoming, past or all. Default upcoming. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/events \ -H "Authorization: Bearer lxk_your_key"
{
"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.
/cad/characters
cad.read
Civilian characters. "John" matches a first or last name; "John Doe" matches both.
searchstring | A name, at least 2 characters. |
discord_idstring | Only characters this person owns. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/characters \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/cad/characters/{id}
cad.read
One character in full: licences, vehicles, firearms, and warrants that are pending or active.
curl https://api.lonexone.com/v1/cad/characters/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"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"
}
]
}
}
/cad/vehicles
cad.read
Registered vehicles. Plates match without spaces and in any case, so abc123 finds "ABC 123".
platestring | A plate. |
vinstring | A VIN. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/vehicles \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/cad/vehicles/{id}
cad.read
One vehicle and its owner.
curl https://api.lonexone.com/v1/cad/vehicles/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 50,
"plate": "ABC 123",
"registration": "valid",
"owner": {
"id": 31,
"name": "John Doe"
}
}
}
/cad/calls
cad.read
Calls with the units on them, newest first. Open calls by default.
statusstring | open, closed or all. Default open. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/calls \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/cad/calls/{id}
cad.read
One call and its units.
curl https://api.lonexone.com/v1/cad/calls/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 210,
"number": 57,
"nature": "Shots fired",
"status": "dispatched",
"units": [
"…"
]
}
}
/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.
naturestring, required | What the call is, up to 80 characters. |
descriptionstring | Details, up to 2000 characters. |
priorityinteger | 1 (most urgent) to 4. Default 2. |
callerstring | Who called. |
locationstring | Street or place. |
postalstring | Postal code. Worked out from coords when left out. |
coordsobject | {"x": 100, "y": -200, "z": 30} in game coordinates. |
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}}'
{
"data": {
"id": 211,
"number": 58,
"nature": "Shots fired",
"priority": 1,
"status": "pending",
"source": "api",
"location": "Grove St",
"postal": "8012"
}
}
/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.
bodystring, required | The note, up to 1000 characters. |
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."}'
{
"data": {
"id": 905,
"call_id": 211,
"body": "Caller reports two suspects heading north on foot.",
"created_at": "2026-11-08T20:04:00+00:00"
}
}
/cad/calls/{id}/close
cad.write
Closes a call and clears the units on it. Closing a call that is already closed changes nothing.
dispositionstring | How it ended, up to 80 characters, like "Report taken". |
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"}'
{
"data": {
"id": 211,
"number": 58,
"status": "closed",
"disposition": "Report taken",
"closed_at": "2026-11-08T20:40:00+00:00",
"units": []
}
}
/cad/units
cad.read
Every unit on duty now, with status, department and the call they are on. Not paged.
curl https://api.lonexone.com/v1/cad/units \ -H "Authorization: Bearer lxk_your_key"
{
"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"
}
]
}
/cad/bolos
cad.read
BOLOs, newest first. Active ones by default.
statusstring | active or all. Default active. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/bolos \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/cad/bolos
cad.write
Issues a BOLO. Returns 201.
kindstring, required | person, vehicle or both. |
titlestring, required | Up to 120 characters. |
threatstring | armed, flight or low. Default low. |
descriptionstring | Up to 2000 characters. |
platestring | Up to 8 characters. |
locationstring | Last seen. |
expires_in_hoursinteger | 1 to 8760. Leave out to keep it until cleared. |
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}'
{
"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"
}
}
/cad/bolos/{id}/clear
cad.write
Clears a BOLO so it stops showing as active. Clearing one already cleared changes nothing.
curl -X POST https://api.lonexone.com/v1/cad/bolos/{id}/clear \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 7,
"title": "Robbery getaway car",
"active": false,
"cleared_at": "2026-11-08T21:00:00+00:00"
}
}
/cad/warrants
cad.read
Warrants, newest first. Active ones by default.
statusstring | pending, active, served, cancelled, denied or all. Default active. |
character_idinteger | Only this character. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/warrants \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/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.
platestring | Spaces are ignored. |
sincedate | Read on or after this date. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/plate-reads \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/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.
curl https://api.lonexone.com/v1/cad/charges \ -H "Authorization: Bearer lxk_your_key"
{
"data": [
{
"id": 41,
"category": "Traffic",
"code": "VC 22350",
"name": "Speeding",
"type": "infraction",
"fine": 250,
"jail_months": 0,
"points": 2
}
]
}
/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.
typestring | citation, warning or arrest. |
statusstring | filed, pending, returned, expunged or all. Default filed. |
character_idinteger | Only this character. |
department_idinteger | Only this department. |
sincedate | Written on or after this date. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/cad/records \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/cad/records/{id}
cad.read
One citation, warning or arrest, with the officer's narrative in notes.
curl https://api.lonexone.com/v1/cad/records/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"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…"
}
}
/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.
typestring, required | citation, warning or arrest. |
officer_discord_idstring, required | The officer writing it. They must be on duty in the CAD. |
character_idinteger, required | Who it is for. |
chargesarray of integers | Charge ids from the penal code. Needed for citations and arrests. |
notesstring | The narrative. Needed for arrests. |
locationstring | Where it happened. |
postalstring | The postal. |
platestring | The vehicle's plate. |
call_idinteger | The call it belongs to. |
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"}'
{
"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.
/staff/on-duty
staff.read
Staff on duty now, highest rank first. Not paged.
curl https://api.lonexone.com/v1/staff/on-duty \ -H "Authorization: Bearer lxk_your_key"
{
"data": [
{
"user": {
"id": 7,
"discord_id": "123456789012345678",
"name": "Ann Cole"
},
"since": "2026-11-08T19:00:00+00:00",
"seconds": 5400
}
]
}
/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.
licensestring | Rockstar license, with or without "license:". |
discordstring | Discord id. |
steamstring | Steam hex. |
fivemstring | Cfx.re account id. |
license2, xbl, livestring | Other identifiers. |
curl https://api.lonexone.com/v1/staff/ban-check \ -H "Authorization: Bearer lxk_your_key"
{
"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"
}
}
}
}
/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.
license, discord, steam, fivemstring | Any identifier. |
searchstring | A name they have played under. |
onlineboolean | Only players in game now. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/staff/players \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/staff/players/{id}
staff.read
One player with every warning, kick, ban, commendation and community service against them, newest first.
curl https://api.lonexone.com/v1/staff/players/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"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"
}
]
}
}
/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.
staff_discord_idstring, required | The staff member giving it. |
player_idinteger, required | From List players. |
typestring, required | warn, kick, ban, commend or service. |
reasonstring, required | Up to 500 characters. |
minutesinteger | Ban length. Leave out for a permanent ban. |
rule_idinteger | The rule broken. |
guideline_reasonstring | Why, when going against the rule's guideline. |
tasksinteger | Community service tasks, 1 to 100. |
server_onlyboolean | A ban for one server only. |
server_idinteger | That server. |
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}'
{
"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"
}
}
/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.
staff_discord_idstring, required | The staff member doing it. |
reasonstring, required | Up to 500 characters. |
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"}'
{
"data": {
"id": 55,
"type": "ban",
"status": "revoked",
"revoked_at": "2026-11-10T09:00:00+00:00"
}
}
/staff/actions
staff.read
Warnings, kicks, bans, commendations and community service across every player, newest first. Active ones by default.
typestring | commend, warn, kick, service or ban. |
statusstring | active, pending, denied, revoked or all. Default active. |
player_idinteger | Only this player. |
staff_discord_idstring | Only ones this staff member gave. |
sincedate | Given on or after this date. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/staff/actions \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/store/payments
store.read
Store payments recorded from Tebex, newest first. Filter by Discord id to see what someone bought.
discord_idstring | Only this buyer. |
statusstring | complete, refunded or chargeback. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/store/payments \ -H "Authorization: Bearer lxk_your_key"
{
"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.
/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.
sincedate | From this date. Default 30 days ago. |
untildate | Up to this date. Default now. |
department_idinteger | Only this department. |
discord_idstring | Only this person. |
curl https://api.lonexone.com/v1/shifts/hours \ -H "Authorization: Bearer lxk_your_key"
{
"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"
}
}
/shifts
shifts.read
Shifts, newest first, with how long each lasted not counting breaks.
openboolean | true for shifts going on now, false for finished ones. |
department_idinteger | Only this department. |
discord_idstring | Only this person. |
sincedate | Started on or after this date. |
untildate | Started before this date. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/shifts \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/applications
applications.read
Applications to your forms, newest first. Open ones (pending or interview) by default.
statusstring | open, pending, interview, accepted, denied, withdrawn or all. Default open. |
form_idinteger | Only this form. |
department_idinteger | Only forms for this department. |
discord_idstring | Only this applicant. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/applications \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/applications/{id}
applications.read
One application, with each question as it was asked and the answer given.
curl https://api.lonexone.com/v1/applications/{id} \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 77,
"status": "pending",
"answers": [
{
"question": "Why do you want to join?",
"answer": "I enjoy patrol roleplay."
}
]
}
}
/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.
decisionstring, required | interview, accept or deny. |
messagestring | Sent to the applicant. Up to 2000 characters. |
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."}'
{
"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.
/training/sessions
training.read
Training sessions. Upcoming and live ones by default, soonest first.
statusstring | upcoming, scheduled, live, ended, cancelled or all. Default upcoming. |
department_idinteger | Only this department. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/training/sessions \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/training/results
training.read
Pass and fail results from test sessions, newest first.
discord_idstring | Only this person. |
test_idinteger | Only this test. |
outcomestring | pass or fail. |
sincedate | Decided on or after this date. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/training/results \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/training/certifications
training.read
Certifications people hold now, newest first. Send current=false to include expired and revoked ones.
discord_idstring | Only this person. |
certification_idinteger | Only this certification. |
currentboolean | Default true. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/training/certifications \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/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.
discord_idstring, required | Who. |
attendancestring, required | attending, unavailable or none. |
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"}'
{
"data": {
"session_id": 9,
"person": {
"id": 19,
"discord_id": "223456789012345678",
"name": "Ben Park"
},
"attendance": "attending",
"attending": 7
}
}
/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.
discord_idstring, required | The trainee. |
certification_idinteger, required | The certification whose programme to start. |
instructor_discord_idstring | Their instructor. |
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"}'
{
"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"
}
}
/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.
discord_idstring, required | Who. |
certification_idinteger, required | Which certification. |
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}'
{
"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
}
}
/training/certifications/{id}/revoke
training.write
Takes away a certification someone holds, by the id from List certifications held. Linked Discord roles follow.
curl -X POST https://api.lonexone.com/v1/training/certifications/{id}/revoke \ -H "Authorization: Bearer lxk_your_key"
{
"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.
/leave
leave.read
Leave requests, newest first. By default, pending and approved ones that haven't finished.
statusstring | open, current (on leave today), pending, approved, denied, cancelled, ended or all. Default open. |
department_idinteger | Only this department. |
discord_idstring | Only this person. |
per_pageinteger | 1 to 100. Default 50. |
curl https://api.lonexone.com/v1/leave \ -H "Authorization: Bearer lxk_your_key"
{
"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
}
}
/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.
discord_idstring, required | Who. |
department_idinteger, required | Their department. |
starts_ondate, required | YYYY-MM-DD, today or later. |
ends_ondate, required | YYYY-MM-DD. |
reasonstring, required | Up to 1000 characters. |
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"}'
{
"data": {
"id": 14,
"starts_on": "2026-11-12",
"ends_on": "2026-11-20",
"days": 9,
"status": "pending"
}
}
/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.
decisionstring, required | approve or deny. |
notestring | Sent to them. Up to 1000 characters. |
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"}'
{
"data": {
"id": 14,
"status": "approved",
"review_note": "Enjoy your break"
}
}
/leave/{id}/end
leave.write
Ends leave that has started, today, and gives them back the roster status they had before.
curl -X POST https://api.lonexone.com/v1/leave/{id}/end \ -H "Authorization: Bearer lxk_your_key"
{
"data": {
"id": 14,
"ends_on": "2026-11-15",
"status": "ended",
"on_leave_now": false
}
}