erlc-api.py is a typed, v2-first Python wrapper for the ER:LC PRC API. It
ships matching sync and async clients, safe defaults for bots, typed dataclass
responses, raw payload escape hatches, and optional utilities for dashboards,
Discord bots, moderation workflows, exports, webhooks, and multi-server reads.
Project links: Changelog, Contributing, Security, and full documentation.
Install the package as erlc-api.py; import it as erlc_api.
pip install erlc-api.pyRequires Python >=3.11.
Sync scripts:
from erlc_api import Client
with Client.from_env() as api:
players = api.players()
print([player.name for player in players])Async apps and bots:
from erlc_api import AsyncClient
async with AsyncClient.from_env() as api:
bundle = await api.bundle()
print(bundle.name, len(bundle.players_list), len(bundle.queue_list))Multi-server dashboards:
from erlc_api import AsyncClient
from erlc_api.multiserver import AsyncMultiServer, ServerRef
servers = [
ServerRef("main", "main-server-key"),
ServerRef("academy", "academy-server-key"),
]
async with AsyncClient() as api:
summary = await AsyncMultiServer(api, servers).aggregate()
print(summary["players"], summary["errors"])Webhook custom commands, after verifying the webhook signature:
from erlc_api.custom_commands import CustomCommandRouter
router = CustomCommandRouter(prefix=";")
@router.command("ping")
def ping(context):
return context.reply("pong", args=list(context.args))
result = await router.dispatch({"Message": ";ping hello"})Set your key through the environment:
set ERLC_SERVER_KEY=your-server-keyUse ERLC_GLOBAL_KEY only when PRC gives your application an Authorization key.
Client/ERLCfor sync scripts.AsyncClient/AsyncERLCfor async bots, web apps, and workers.- Flat endpoint methods:
players(),staff(),queue(),vehicles(),bans(),command(), and log helpers. bundle()for a dashboard-ready server snapshot without remembering include flags.- Frozen dataclass models with
.raw,.extra, and.to_dict(). raw=Truewhen you need exact PRC payloads.- Dynamic rate limiting enabled by default.
- Explicit opt-in utilities that stay lazy until imported.
from erlc_api import Client
with Client.from_env() as api:
server = api.server()
dashboard = api.bundle()
all_data = api.bundle("all")
command_logs = api.logs("command")
print(server.name)
print(dashboard.players_list)
print(command_logs[0].command if command_logs else "no commands")api.server() stays lean. Use api.bundle() when you want player, staff,
queue, vehicle, and emergency-call data in one typed ServerBundle.
Dynamic rate limiting is enabled by default. For production bots, keep
rate_limited=True; if the same reads repeat often, wrap the client in
CachedClient or AsyncCachedClient for explicit TTL caching.
For larger deployments, see Scaling Your App.
Command execution is explicit. For bot or web input, validate locally before sending anything to PRC:
from erlc_api import Client, CommandPolicy, cmd
policy = CommandPolicy(allowed={"h", "pm"}, max_length=120)
with Client.from_env() as api:
preview = api.preview_command(cmd.h("Restart in 5 minutes"), policy=policy)
if preview.allowed:
result = api.command(preview.command, policy=policy)
print(result.message)preview_command(...) never sends HTTP. command(..., policy=policy) validates
before the request and raises CommandPolicyError if blocked.
Base installs only depend on httpx. Extras stay opt-in:
| Extra | Used by |
|---|---|
webhooks |
Event webhook Ed25519 signature verification |
roblox |
Discoverable install extra for Roblox user/profile lookup |
export |
XLSX export helpers |
time |
Enhanced time parsing |
rich |
Rich terminal tables |
scheduling |
Advanced scheduling integrations around watchers |
location |
Optional map overlays |
utils |
Utility extras except webhooks |
all |
Everything optional |
Example:
pip install "erlc-api.py[webhooks,export]"The core import remains lightweight:
from erlc_api import AsyncClient, Client, CommandPolicy, PermissionLevel, cmd
from erlc_api.roblox import AsyncRobloxClient
from erlc_api.vehicles import VehicleTools
from erlc_api.cache import AsyncCachedClient
from erlc_api.webhooks import assert_valid_event_webhook_signatureAdvanced modules include caching, filters, finders, sorting, grouping, analytics, export, waiters, watchers, moderation helpers, Discord payload helpers, command flows, webhooks, Roblox user/profile lookup, vehicle tools, emergency-call tools, and multi-server reads.
Full documentation is at https://fortune1243.github.io/erlc-api.
Useful starting points:
- How It Works — mental model, sync vs async, rate limits
- Endpoint Reference — every API method
- Getting Started — first calls, commands, multi-server
- Migration to v3 — upgrade from v2
Runnable examples live in examples.
pip install -e .[dev]
python -m ruff check src tests scripts examples
$env:PYTHONPATH = "src"; python -m pytest -qBefore release work:
python -m build
python -m twine check dist/*Bug reports and pull requests are welcome on the GitHub repository. Please read CONTRIBUTING.md before opening a larger change.
Before submitting, run ruff check and pytest -q locally.
For usage questions, open a GitHub issue or contact Avi on Discord as
avi1243. Never share raw server keys or global keys in public logs, issues, or
chat messages.
This project uses a custom attribution license. You may use and modify the wrapper under the terms in LICENSE, and redistribution or derivative work must preserve the required attribution. The attribution requirement is about crediting the wrapper and its author; it does not require exposing API keys, server details, or runtime secrets.
Independent community wrapper, not an official PRC product.