Forest Logo
search
package_2

sonoran-lua

By @sonoransoftwaregit

Roblox

Mirrored

Sonoran.lua

Sonoran.lua is a Lua SDK for Sonoran CAD v2 endpoints with shared client code for FiveM and Roblox runtimes.

Installation

FiveM

Install from LuaRocks:

luarocks install sonoran.lua

LuaRocks package: sonoran.lua on LuaRocks

Or use the generated FiveM resource release asset and start it before resources that consume it.

ensure Sonoran.lua

In your consuming resource:

fx_version 'cerulean'
game 'gta5'
lua54 'yes'

server_scripts {
  'server.lua'
}

dependency 'Sonoran.lua'

Roblox

Install from Wally:

[dependencies]
Sonoran = "sonoransoftwaregit/sonoran-lua@^0.1.0"

Then require the package module:

local Sonoran = require(ReplicatedStorage.Packages.Sonoran)

Usage

FiveM resource usage:

local Sonoran = require("sonoran")

local sonoran = exports["Sonoran.lua"]:createClient({
  product = Sonoran.productEnums.CAD,
  apiKey = "your-cad-api-key",
  communityId = "your-community-id",
  apiUrl = "https://api.sonorancad.com",
  defaultServerId = 1,
  timeoutMs = 30000,
  logLevel = Sonoran.logLevels.ERROR
})

sonoran:setLogLevel(Sonoran.logLevels.DEBUG)
sonoran:setRoomId(1)

Roblox usage:

local sonoran = Sonoran.createClient({
  product = Sonoran.productEnums.CAD,
  apiKey = "your-cad-api-key",
  communityId = "your-community-id",
  apiUrl = "https://api.sonorancad.com",
  defaultServerId = 1,
  timeoutMs = 30000,
  logLevel = Sonoran.logLevels.ERROR
})

sonoran:setLogLevel(Sonoran.logLevels.DEBUG)

Config

  • apiKey: required for authenticated endpoints.
  • product: required; use Sonoran.productEnums.CAD, Sonoran.productEnums.CMS, or Sonoran.productEnums.RADIO.
  • communityId: optional; used by getLoginPageV2() when no explicit communityId is supplied.
  • apiUrl: optional; defaults to https://api.sonorancad.com.
  • defaultServerId: optional; defaults to 1 for CAD/CMS-style server-scoped helpers. Radio v2 helpers resolve the community route from communityId.
  • roomId: optional for CAD/CMS and required for Radio v2 room-scoped helpers.
  • headers: optional extra headers merged into every request.
  • timeoutMs: optional timeout for the FiveM adapter; defaults to 30000.
  • logLevel: optional; Sonoran.logLevels.ERROR by default. Supported values are OFF, ERROR, and DEBUG.

Debug Logging

Use setLogLevel() to toggle HTTP debug output at runtime:

sonoran:setLogLevel(Sonoran.logLevels.DEBUG)

Use setRoomId() to update the Radio room used by later room-scoped requests without creating a new client:

sonoran:setRoomId(1)

Use ERROR to only print failed requests and rate-limit events:

sonoran:setLogLevel(Sonoran.logLevels.ERROR)

When DEBUG is enabled, Sonoran.lua prints every HTTP request and response to the console, including the method, URL, headers, body, response status, and response headers. Sensitive request values such as Authorization and API-key style fields are redacted in both DEBUG and ERROR logs.

Response Shape

All public methods return:

{ success = true, data = ... }

or:

{ success = false, reason = ... }

Successful JSON responses are decoded automatically. Plain-text error responses are returned as strings. 204 No Content responses return data = nil.

Rate Limit Handling

For CAD v2 endpoints, Sonoran.lua automatically retries 429 Too Many Requests responses up to 2 times when it can safely honor the server's wait window. The client checks Retry-After first, including both delta-seconds and HTTP-date formats, then falls back to RateLimit-Reset, X-RateLimit-Reset, and finally a short exponential backoff. If the server asks for a longer wait than the client's automatic retry limit, or the active adapter cannot sleep, the request fails instead of retrying too early.

Examples

General endpoint:

local version = sonoran.cad:getVersionV2()
if version.success then
  print(version.data)
end

Civilian endpoint:

local characters = sonoran.cad:getCharactersV2({
  roblox = 1234567890
})

if characters.success then
  print(("Found %s character(s)"):format(#characters.data))
end

Emergency endpoint:

local created = sonoran.cad:createDispatchCallV2({
  serverId = 1,
  origin = 1,
  status = 1,
  priority = 1,
  block = "123",
  address = "Main St",
  postal = "100",
  title = "Traffic Stop",
  code = "TS",
  description = "Blue sedan heading north",
  notes = {},
  communityUserIds = { "1234567890" }
})

if not created.success then
  print(json.encode(created.reason))
end

Public API

All CAD v2 helpers are available under client.cad.*. The root-level methods are still present for backward compatibility.

General

  • getLoginPageV2(params?)
  • checkApiIdV2(apiId)
  • applyPermissionKeyV2(data)
  • banUserV2(data)
  • getPenalCodesV2()
  • setPenalCodesV2(codes)
  • setApiIdsV2(data)
  • getTemplatesV2(recordTypeId?)
  • createRecordV2(data)
  • updateRecordV2(recordId, data)
  • removeRecordV2(recordId)
  • sendRecordDraftV2(data)
  • lookupV2(data)
  • lookupByValueV2(data)
  • lookupCustomV2(data)
  • getAccountV2(query?)
  • getAccountsV2(query?)
  • createCommunityLinkV2(data)
  • checkCommunityLinkV2(data)
  • setCommunityLinkV2(data)
  • setAccountPermissionsV2(data)
  • heartbeatV2(serverId, playerCount)
  • getVersionV2()
  • getServersV2()
  • setServersV2(servers, deployMap?)
  • verifySecretV2(secret)
  • authorizeStreetSignsV2(serverId?)
  • setPostalsV2(postals)
  • sendPhotoV2(data)
  • uploadBodycamRecordingV2(data)
  • getInfoV2()

Civilian

  • getCharactersV2(query?)
  • removeCharacterV2(characterId)
  • setSelectedCharacterV2(data)
  • getCharacterLinksV2(query?)
  • addCharacterLinkV2(syncId, data)
  • removeCharacterLinkV2(syncId, data)

Emergency

  • getUnitsV2(query?)
  • getCallsV2(query?)
  • getCurrentCallV2(accountUuid)
  • updateUnitLocationsV2(data)
  • setUnitPanicV2(data)
  • setUnitStatusV2(data)
  • kickUnitV2(data)
  • getIdentifiersV2(accountUuid)
  • getAccountUnitsV2(data)
  • selectIdentifierV2(accountUuid, identId)
  • createIdentifierV2(accountUuid, data)
  • updateIdentifierV2(accountUuid, identId, data)
  • deleteIdentifierV2(accountUuid, identId)
  • addIdentifiersToGroupV2(data)
  • createEmergencyCallV2(data)
  • deleteEmergencyCallV2(callId, serverId?)
  • getDispatchTemplatesV2(templateId?)
  • createDispatchCallV2(data)
  • createCustomDispatchCallV2(data)
  • updateDispatchCallV2(callId, data)
  • attachUnitsToDispatchCallV2(callId, data)
  • detachUnitsFromDispatchCallV2(data)
  • setDispatchPostalV2(callId, postal, serverId?)
  • setDispatchPrimaryV2(callId, identId, trackPrimary?, serverId?)
  • addDispatchNoteV2(callId, data)
  • closeDispatchCallsV2(callIds, serverId?)
  • updateStreetSignsV2(data)
  • setStreetSignConfigV2(signs, serverId?)
  • setAvailableCalloutsV2(callouts, serverId?)
  • getPagerConfigV2(serverId?)
  • setPagerConfigV2(data)
  • setStationsV2(config, serverId?) Sends the provided top-level station payload as-is. Pass locations, tones, and unitColors directly on the request body.
  • getBlipsV2(serverId?)
  • createBlipV2(data)
  • updateBlipV2(blipId, data)
  • deleteBlipsV2(ids, serverId?)

Notes

  • Account-targeted CAD v2 helpers accept accountUuid, communityUserId, roblox, discord, and legacy apiId where supported by the backend.
  • updateUnitLocationsV2(data) uses the HTTP v2 endpoint for slower unit location updates, and each update can target communityUserId, roblox, or discord.
  • Unit location updates can target communityUserId, roblox, or discord through the v2 HTTP endpoint.
  • FiveM uses PerformHttpRequest, promise.new(), and Citizen.Await.
  • Roblox uses HttpService:RequestAsync().
  • Radio, CMS, and legacy CAD endpoints are intentionally out of scope for this initial port.

Package Details

Install command (Click to copy)


Version

0.1.61

License

MIT

check_circle

Safe for commercial use

infoLicense identified from the packaged LICENSE file; the manifest's declared license ("PolyForm-Noncommercial-1.0.0") is not a recognized identifier.

Automated license review — not legal advice.