Files
acc-server-manager/documentation/API.md
2025-06-29 21:59:41 +02:00

15 KiB

API Documentation for ACC Server Manager

Overview

The ACC Server Manager provides a comprehensive REST API for managing Assetto Corsa Competizione dedicated servers. This API enables full control over server instances, configurations, user management, and monitoring through HTTP endpoints.

Base URL

http://localhost:3000/api/v1

Authentication

All API endpoints (except public ones) require authentication via JWT tokens.

Authentication Header

Authorization: Bearer <your-jwt-token>

Token Expiration

  • Default token lifetime: 24 hours
  • Tokens should be refreshed before expiration
  • Failed authentication returns HTTP 401

Rate Limiting

The API implements multiple layers of rate limiting:

  • Global: 100 requests per minute per IP
  • Authentication: 5 attempts per 15 minutes per IP
  • API Endpoints: 60 requests per minute per IP

Rate limit exceeded responses return HTTP 429 with retry information.

Response Format

All API responses follow a consistent JSON format:

Success Response

{
  "success": true,
  "data": {
    // Response data
  },
  "message": "Operation completed successfully"
}

Error Response

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable error message",
    "details": {}
  }
}

HTTP Status Codes

Status Code Description
200 OK - Request successful
201 Created - Resource created successfully
400 Bad Request - Invalid request data
401 Unauthorized - Authentication required
403 Forbidden - Insufficient permissions
404 Not Found - Resource not found
409 Conflict - Resource already exists
422 Unprocessable Entity - Validation failed
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Server error

API Endpoints

Authentication

Login

POST /api/v1/auth/login

Request Body:

{
  "username": "string",
  "password": "string"
}

Response:

{
  "success": true,
  "data": {
    "token": "jwt-token-string",
    "user": {
      "id": "uuid",
      "username": "string",
      "role": {
        "id": "uuid",
        "name": "string",
        "permissions": []
      }
    }
  }
}

Register User

POST /api/v1/auth/register

Requires: user.create permission

Request Body:

{
  "username": "string",
  "password": "string",
  "roleId": "uuid"
}

Get Current User

GET /api/v1/auth/me

Requires: Authentication

Response:

{
  "success": true,
  "data": {
    "id": "uuid",
    "username": "string",
    "role": {
      "id": "uuid",
      "name": "string",
      "permissions": []
    }
  }
}

Server Management

List Servers

GET /api/v1/servers

Requires: server.read permission

Query Parameters:

  • page (integer): Page number (default: 1)
  • limit (integer): Items per page (default: 10)
  • search (string): Search term
  • status (string): Filter by status (running, stopped, error)

Response:

{
  "success": true,
  "data": {
    "servers": [
      {
        "id": 1,
        "name": "string",
        "ip": "string",
        "port": 9600,
        "path": "string",
        "serviceName": "string",
        "status": "string",
        "dateCreated": "2024-01-01T00:00:00Z"
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 10,
      "total": 50,
      "pages": 5
    }
  }
}

Create Server

POST /api/v1/servers

Requires: server.create permission

Request Body:

{
  "name": "string",
  "ip": "string",
  "port": 9600,
  "path": "string"
}

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "name": "string",
    "ip": "string",
    "port": 9600,
    "path": "string",
    "serviceName": "string",
    "status": "created",
    "dateCreated": "2024-01-01T00:00:00Z"
  }
}

Get Server Details

GET /api/v1/servers/{id}

Requires: server.read permission

Path Parameters:

  • id (integer): Server ID

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "name": "string",
    "ip": "string",
    "port": 9600,
    "path": "string",
    "serviceName": "string",
    "status": "string",
    "dateCreated": "2024-01-01T00:00:00Z",
    "configs": [],
    "statistics": {}
  }
}

Update Server

PUT /api/v1/servers/{id}

Requires: server.update permission

Path Parameters:

  • id (integer): Server ID

Request Body:

{
  "name": "string",
  "ip": "string",
  "port": 9600,
  "path": "string"
}

Delete Server

DELETE /api/v1/servers/{id}

Requires: server.delete permission

Path Parameters:

  • id (integer): Server ID

Start Server

POST /api/v1/servers/{id}/start

Requires: server.control permission

Stop Server

POST /api/v1/servers/{id}/stop

Requires: server.control permission

Restart Server

POST /api/v1/servers/{id}/restart

Requires: server.control permission

Configuration Management

Get Configuration File

GET /api/v1/servers/{id}/config/{file}

Requires: config.read permission

Path Parameters:

  • id (integer): Server ID
  • file (string): Configuration file name (configuration, event, eventRules, settings)

Response:

{
  "success": true,
  "data": {
    "file": "configuration",
    "content": {},
    "lastModified": "2024-01-01T00:00:00Z"
  }
}

Update Configuration File

PUT /api/v1/servers/{id}/config/{file}

Requires: config.update permission

Path Parameters:

  • id (integer): Server ID
  • file (string): Configuration file name

Query Parameters:

  • restart (boolean): Restart server after update (default: false)
  • override (boolean): Override validation warnings (default: false)

Request Body:

{
  "tcpPort": 9600,
  "udpPort": 9600,
  "maxConnections": 30,
  "registerToLobby": 1,
  "serverName": "My ACC Server",
  "password": "",
  "adminPassword": "admin123",
  "trackMedalsRequirement": 0,
  "safetyRatingRequirement": -1,
  "racecraftRatingRequirement": -1,
  "configVersion": 1
}

Validate Configuration

POST /api/v1/servers/{id}/config/{file}/validate

Requires: config.read permission

Request Body: Configuration object to validate

Response:

{
  "success": true,
  "data": {
    "valid": true,
    "errors": [],
    "warnings": []
  }
}

Steam Integration

Get Steam Credentials

GET /api/v1/steam/credentials

Requires: steam.read permission

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "username": "steam_username",
    "dateCreated": "2024-01-01T00:00:00Z",
    "lastUpdated": "2024-01-01T00:00:00Z"
  }
}

Update Steam Credentials

PUT /api/v1/steam/credentials

Requires: steam.update permission

Request Body:

{
  "username": "steam_username",
  "password": "steam_password"
}

Install/Update Server

POST /api/v1/steam/install

Requires: steam.install permission

Request Body:

{
  "serverId": 1,
  "validate": true,
  "beta": false
}

User Management

List Users

GET /api/v1/users

Requires: user.read permission

Query Parameters:

  • page (integer): Page number
  • limit (integer): Items per page
  • search (string): Search term

Response:

{
  "success": true,
  "data": {
    "users": [
      {
        "id": "uuid",
        "username": "string",
        "role": {
          "id": "uuid",
          "name": "string"
        },
        "createdAt": "2024-01-01T00:00:00Z"
      }
    ],
    "pagination": {}
  }
}

Create User

POST /api/v1/users

Requires: user.create permission

Update User

PUT /api/v1/users/{id}

Requires: user.update permission

Delete User

DELETE /api/v1/users/{id}

Requires: user.delete permission

Role and Permission Management

List Roles

GET /api/v1/roles

Requires: role.read permission

Create Role

POST /api/v1/roles

Requires: role.create permission

Request Body:

{
  "name": "string",
  "description": "string",
  "permissions": ["permission1", "permission2"]
}

List Permissions

GET /api/v1/permissions

Requires: permission.read permission

Response:

{
  "success": true,
  "data": [
    {
      "name": "server.create",
      "description": "Create new servers",
      "category": "server"
    }
  ]
}

Monitoring and Analytics

Get Server Statistics

GET /api/v1/servers/{id}/stats

Requires: stats.read permission

Query Parameters:

  • from (string): Start date (ISO 8601)
  • to (string): End date (ISO 8601)
  • granularity (string): hour, day, week, month

Response:

{
  "success": true,
  "data": {
    "totalPlaytime": 3600,
    "playerCount": [],
    "sessionTypes": [],
    "dailyActivity": [],
    "recentSessions": []
  }
}

Get System Health

GET /api/v1/system/health

Public endpoint

Response:

{
  "success": true,
  "data": {
    "status": "healthy",
    "version": "1.0.0",
    "uptime": 3600,
    "database": "connected",
    "services": {
      "steam": "available",
      "nssm": "available"
    }
  }
}

Lookup Data

Get Tracks

GET /api/v1/lookup/tracks

Public endpoint

Response:

{
  "success": true,
  "data": [
    {
      "name": "monza",
      "uniquePitBoxes": 29,
      "privateServerSlots": 60
    }
  ]
}

Get Car Models

GET /api/v1/lookup/cars

Public endpoint

Get Driver Categories

GET /api/v1/lookup/driver-categories

Public endpoint

Get Cup Categories

GET /api/v1/lookup/cup-categories

Public endpoint

Get Session Types

GET /api/v1/lookup/session-types

Public endpoint

Webhooks

The API supports webhook notifications for server events:

Server Status Changes

{
  "event": "server.status.changed",
  "serverId": 1,
  "serverName": "My Server",
  "oldStatus": "stopped",
  "newStatus": "running",
  "timestamp": "2024-01-01T00:00:00Z"
}

Configuration Updates

{
  "event": "server.config.updated",
  "serverId": 1,
  "serverName": "My Server",
  "configFile": "configuration",
  "userId": "uuid",
  "timestamp": "2024-01-01T00:00:00Z"
}

Error Codes

Code Description
AUTH_REQUIRED Authentication required
AUTH_INVALID Invalid credentials
AUTH_EXPIRED Token expired
PERMISSION_DENIED Insufficient permissions
VALIDATION_FAILED Request validation failed
RESOURCE_NOT_FOUND Requested resource not found
RESOURCE_EXISTS Resource already exists
RATE_LIMIT_EXCEEDED Rate limit exceeded
SERVER_ERROR Internal server error
SERVICE_UNAVAILABLE External service unavailable

SDK Examples

JavaScript/Node.js

const axios = require('axios');

class ACCServerManagerAPI {
  constructor(baseUrl, token) {
    this.baseUrl = baseUrl;
    this.token = token;
    this.client = axios.create({
      baseURL: baseUrl,
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async getServers() {
    const response = await this.client.get('/servers');
    return response.data;
  }

  async createServer(serverData) {
    const response = await this.client.post('/servers', serverData);
    return response.data;
  }

  async updateConfig(serverId, file, config, restart = false) {
    const response = await this.client.put(
      `/servers/${serverId}/config/${file}?restart=${restart}`,
      config
    );
    return response.data;
  }
}

// Usage
const api = new ACCServerManagerAPI('http://localhost:3000/api/v1', 'your-jwt-token');
const servers = await api.getServers();

Python

import requests

class ACCServerManagerAPI:
    def __init__(self, base_url, token):
        self.base_url = base_url
        self.headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }
    
    def get_servers(self):
        response = requests.get(f'{self.base_url}/servers', headers=self.headers)
        return response.json()
    
    def create_server(self, server_data):
        response = requests.post(
            f'{self.base_url}/servers',
            json=server_data,
            headers=self.headers
        )
        return response.json()

# Usage
api = ACCServerManagerAPI('http://localhost:3000/api/v1', 'your-jwt-token')
servers = api.get_servers()

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

type ACCServerManagerAPI struct {
    BaseURL string
    Token   string
    Client  *http.Client
}

func NewACCServerManagerAPI(baseURL, token string) *ACCServerManagerAPI {
    return &ACCServerManagerAPI{
        BaseURL: baseURL,
        Token:   token,
        Client:  &http.Client{},
    }
}

func (api *ACCServerManagerAPI) request(method, endpoint string, body interface{}) (*http.Response, error) {
    var reqBody bytes.Buffer
    if body != nil {
        json.NewEncoder(&reqBody).Encode(body)
    }
    
    req, err := http.NewRequest(method, api.BaseURL+endpoint, &reqBody)
    if err != nil {
        return nil, err
    }
    
    req.Header.Set("Authorization", "Bearer "+api.Token)
    req.Header.Set("Content-Type", "application/json")
    
    return api.Client.Do(req)
}

func (api *ACCServerManagerAPI) GetServers() (interface{}, error) {
    resp, err := api.request("GET", "/servers", nil)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var result interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    return result, nil
}

Best Practices

Authentication

  1. Store JWT tokens securely (httpOnly cookies for web apps)
  2. Implement token refresh mechanism
  3. Handle authentication errors gracefully
  4. Use HTTPS in production

Rate Limiting

  1. Implement exponential backoff for rate-limited requests
  2. Cache responses when appropriate
  3. Use batch operations when available
  4. Monitor rate limit headers

Error Handling

  1. Always check response status codes
  2. Handle network errors gracefully
  3. Implement retry logic for transient errors
  4. Log errors for debugging

Performance

  1. Use pagination for large datasets
  2. Implement client-side caching
  3. Use WebSockets for real-time updates
  4. Compress request/response bodies

Support

For API support:

  • Documentation: Check this guide and interactive Swagger UI
  • Issues: Report API bugs via GitHub Issues
  • Community: Join community discussions for help
  • Professional Support: Contact maintainers for enterprise support

Note: This API is versioned. Breaking changes will result in a new API version. Always specify the version in your requests.