🚔 ER:LC API Wrapper
A comprehensive, lightweight, and fully-typed API wrapper for Emergency Response: Liberty County (ER:LC) with 100% API coverage, robust error handling, and TypeScript support.
✨ Features
- 🎯 100% API Coverage - All ER:LC API endpoints supported
- 🛡️ Robust Error Handling - Comprehensive error catching and meaningful error messages
- 📝 Full TypeScript Support - Complete type definitions for all methods and responses
- ⚡ Optimized Performance - Efficient request handling with timeout management
- 🔒 Secure - Built-in validation and secure token handling
- 📚 Well Documented - Extensive documentation and examples
- 🚀 Easy to Use - Simple, intuitive API design
📦 Installation
npm install erlc-api
bun add erlc-api
🚀 Quick Start
Basic Setup
const erlc = require("erlc-api");
// Initialize the client with your global token
const client = new erlc.Client({
globalToken: "your-global-token-here", // Get this from ER:LC developers
});
// Register your client
client.config();
TypeScript Setup
import erlc from "erlc-api";
const client = new erlc.Client({
globalToken: "your-global-token-here",
});
client.config();
📖 API Methods
🖥️ Server Information
Get Server Details
const getServerInfo = async () => {
try {
const serverToken = "your-server-api-key"; // From Server Settings
const server = await erlc.getServer(serverToken);
console.log(server);
/*
Expected Response:
{
Name: "Your Server Name",
OwnerUsername: "ServerOwner",
CoOwnerUsernames: ["CoOwner1", "CoOwner2"],
CurrentPlayers: 25,
MaxPlayers: 40,
JoinKey: "ABC123",
AccVerifiedReq: "Disabled", // "Email" | "Phone/ID"
TeamBalance: true,
VanityURL: "https://policeroleplay.community/join?code=ABC123"
}
*/
} catch (error) {
console.error("Error fetching server info:", error.message);
}
};
Get Current Players
const getCurrentPlayers = async () => {
try {
const players = await erlc.getPlayers(serverToken);
console.log(players);
/*
Expected Response:
[
{
Player: "PlayerName:123456789",
Permission: "Server Owner", // "Member" | "Moderator" | "Server Administrator"
Team: "Police" // "Civilian" | "Fire" | "Sheriff"
}
]
*/
} catch (error) {
console.error("Error fetching players:", error.message);
}
};
Get Server Queue
const getServerQueue = async () => {
try {
const queue = await erlc.getQueue(serverToken);
console.log(`Players in queue: ${queue.length}`);
} catch (error) {
console.error("Error fetching queue:", error.message);
}
};
👥 Staff Management
Get Staff Information
const getStaffInfo = async () => {
try {
const staff = await erlc.getStaff(serverToken);
console.log(staff);
/*
Expected Response:
{
CoOwners: [123456789, 987654321],
Admins: { "123456789": "AdminName" },
Mods: { "987654321": "ModName" }
}
*/
} catch (error) {
console.error("Error fetching staff:", error.message);
}
};
📊 Server Logs
Get Join/Leave Logs
const getJoinLogs = async () => {
try {
const logs = await erlc.getJoinLogs(serverToken);
logs.forEach((log) => {
const action = log.Join ? "joined" : "left";
console.log(
`${log.Player} ${action} at ${new Date(log.Timestamp * 1000)}`
);
});
} catch (error) {
console.error("Error fetching join logs:", error.message);
}
};
Get Kill Logs
const getKillLogs = async () => {
try {
const kills = await erlc.getKillLogs(serverToken);
kills.forEach((kill) => {
console.log(
`${kill.Killer} killed ${kill.Killed} at ${new Date(
kill.Timestamp * 1000
)}`
);
});
} catch (error) {
console.error("Error fetching kill logs:", error.message);
}
};
Get Command Logs
const getCommandLogs = async () => {
try {
const commands = await erlc.getCommandLogs(serverToken);
commands.forEach((cmd) => {
console.log(`${cmd.Player} executed: ${cmd.Command}`);
});
} catch (error) {
console.error("Error fetching command logs:", error.message);
}
};
Get Moderator Call Logs
const getModCalls = async () => {
try {
const modcalls = await erlc.getModcallLogs(serverToken);
modcalls.forEach((call) => {
const status = call.Moderator
? `answered by ${call.Moderator}`
: "unanswered";
console.log(`${call.Caller} made a modcall - ${status}`);
});
} catch (error) {
console.error("Error fetching modcall logs:", error.message);
}
};
🚗 Vehicle Management
Get Server Vehicles
const getVehicles = async () => {
try {
const vehicles = await erlc.getVehicles(serverToken);
vehicles.forEach((vehicle) => {
console.log(
`${vehicle.Name} owned by ${vehicle.Owner} - Texture: ${
vehicle.Texture || "Default"
}`
);
});
} catch (error) {
console.error("Error fetching vehicles:", error.message);
}
};
🔨 Server Management
Execute Server Commands
const executeCommand = async () => {
try {
const success = await erlc.runCommand(
serverToken,
":h Welcome to our server!"
);
if (success) {
console.log("Command executed successfully!");
}
} catch (error) {
console.error("Error executing command:", error.message);
}
};
Get Server Bans
const getBannedPlayers = async () => {
try {
const bans = await erlc.getBans(serverToken);
Object.entries(bans).forEach(([playerId, playerName]) => {
console.log(`${playerName} (${playerId}) is banned`);
});
} catch (error) {
console.error("Error fetching bans:", error.message);
}
};
🛠️ Advanced Usage
Error Handling Best Practices
const handleApiCall = async () => {
try {
const result = await erlc.getServer(serverToken);
return result;
} catch (error) {
// Handle specific error types
if (error.status === 401) {
console.error("Authentication failed - check your tokens");
} else if (error.status === 404) {
console.error("Server not found - check your server token");
} else if (error.message.includes("Network error")) {
console.error("Connection issue - check your internet connection");
} else if (error.message.includes("timeout")) {
console.error("Request timed out - try again later");
} else {
console.error("Unexpected error:", error.message);
}
throw error; // Re-throw if needed
}
};
Batch Operations
const getServerOverview = async (serverToken) => {
try {
// Execute multiple API calls concurrently
const [serverInfo, players, staff, vehicles] = await Promise.all([
erlc.getServer(serverToken),
erlc.getPlayers(serverToken),
erlc.getStaff(serverToken),
erlc.getVehicles(serverToken),
]);
return {
server: serverInfo,
playerCount: players.length,
staffCount:
Object.keys(staff.Admins).length + Object.keys(staff.Mods).length,
vehicleCount: vehicles.length,
};
} catch (error) {
console.error("Error getting server overview:", error.message);
throw error;
}
};
🔑 Authentication
Getting Your Tokens
- Global Token: Contact ER:LC developers through their Discord to request increased API limits
- Server Token: Found in your server settings within ER:LC
Token Security
// ❌ Don't hardcode tokens
const client = new erlc.Client({
globalToken: "your-token-here",
});
// ✅ Use environment variables
const client = new erlc.Client({
globalToken: process.env.ERLC_GLOBAL_TOKEN,
});
📝 TypeScript Support
The package includes comprehensive TypeScript definitions:
import erlc, { ServerStatus, ServerPlayer, JoinLog } from "erlc-api";
const client = new erlc.Client({
globalToken: process.env.ERLC_GLOBAL_TOKEN!,
});
client.config();
// Fully typed responses
const server: ServerStatus = await erlc.getServer(serverToken);
const players: ServerPlayer[] = await erlc.getPlayers(serverToken);
const joinLogs: JoinLog[] = await erlc.getJoinLogs(serverToken);
⚡ Performance Tips
- Use Promise.all() for concurrent requests when fetching multiple endpoints
- Implement caching for frequently accessed data that doesn't change often
- Handle rate limits by implementing retry logic with exponential backoff
- Use timeouts - all methods have built-in 10-15 second timeouts
🐛 Error Types
The wrapper provides detailed error information:
- Network Errors: Connection issues, DNS resolution failures
- Authentication Errors: Invalid tokens, insufficient permissions
- API Errors: Server-side errors with status codes and messages
- Validation Errors: Invalid input parameters
- Timeout Errors: Requests that take too long to complete
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Links
- Discord Bot: Invite to your server
- API Documentation: PRC API Docs
- Discord Support: Join PRC Discord
- Custom Liveries: Browse Collection
👨💻 Credits
- Library Development: Egologics
- NPM Package: ERLC-API
- API Development: Police Roleplay Community
- Community Support: PRC Discord Community
Made with ❤️ for the ER:LC community
⭐ Star us on GitHub • 💬 Join our Discord • 🐦 Follow on Twitter