Skip to content

Authentication

Arcadium API uses Bearer token authentication for all protected endpoints.

API Token Types

User Tokens

Created by users in Account Settings, inherit the user's cluster permissions.

Use cases:

  • Integrations with external tools
  • Custom scripts and automation
  • Third-party applications

Agent Tokens

Issued to agents during machine registration, used for WebSocket authentication.

Use cases:

  • Agent ↔ API communication
  • Machine authentication
  • Server management

Creating an API Token

Via Dashboard

  1. Navigate to Account Settings → API Tokens
  2. Click Create New Token
  3. Configure token:
    • Name - Descriptive identifier
    • Expires - Optional expiration date
    • Scopes - Select clusters (inherits your role per cluster)
  4. Click Generate Token
  5. Copy token immediately - shown only once

Token Security

Save your token securely. It cannot be retrieved again after creation.

Token Properties

json
{
  "id": "tok_abc123",
  "name": "CI/CD Pipeline",
  "token": "arcadium_live_...", // Only shown once
  "userId": "usr_xyz789",
  "expiresAt": "2025-12-31T23:59:59Z",
  "createdAt": "2024-01-15T10:30:00Z",
  "lastUsedAt": "2024-01-20T14:22:11Z"
}

Using API Tokens

HTTP Header

All API requests require the Authorization header:

http
GET /api/v1/clusters/{clusterId}/servers
Host: api.arcadiumpanel.com
Authorization: Bearer arcadium_live_abc123xyz...
Content-Type: application/json

cURL Example

bash
curl -X GET \
  https://api.arcadiumpanel.com/api/v1/clusters/clu_123/servers \
  -H "Authorization: Bearer arcadium_live_abc123xyz..." \
  -H "Content-Type: application/json"

JavaScript Example

javascript
const response = await fetch(
  'https://api.arcadiumpanel.com/api/v1/clusters/clu_123/servers',
  {
    headers: {
      'Authorization': 'Bearer arcadium_live_abc123xyz...',
      'Content-Type': 'application/json'
    }
  }
);

const servers = await response.json();

Python Example

python
import requests

headers = {
    'Authorization': 'Bearer arcadium_live_abc123xyz...',
    'Content-Type': 'application/json'
}

response = requests.get(
    'https://api.arcadiumpanel.com/api/v1/clusters/clu_123/servers',
    headers=headers
)

servers = response.json()

Token Permissions

Tokens inherit the user's cluster role:

Cluster RoleToken Permissions
OWNERFull API access to cluster resources
ADMINManage servers, players, tasks (no billing)
MODERATORRead servers, manage players only
VIEWERRead-only access to all resources

Permission Example

typescript
// Token with ADMIN role on Cluster A, VIEWER on Cluster B

// Cluster A - Can create servers ✅
POST /api/v1/clusters/clu_a/servers
Authorization: Bearer <token>
201 Created

// Cluster B - Cannot create servers ❌
POST /api/v1/clusters/clu_b/servers
Authorization: Bearer <token>
403 Forbidden

// Cluster B - Can read servers ✅
GET /api/v1/clusters/clu_b/servers
Authorization: Bearer <token>
200 OK

Error Responses

401 Unauthorized

Missing or invalid token:

json
{
  "statusCode": 401,
  "message": "Unauthorized",
  "error": "Invalid or expired token"
}

Causes:

  • Missing Authorization header
  • Malformed token
  • Token expired or revoked
  • Token doesn't exist

Solution:

  • Verify token format: Bearer arcadium_live_...
  • Check token hasn't been deleted/revoked
  • Create new token if expired

403 Forbidden

Valid token but insufficient permissions:

json
{
  "statusCode": 403,
  "message": "Forbidden",
  "error": "Insufficient permissions for this resource"
}

Causes:

  • Token's cluster role lacks required permission
  • Trying to access cluster you're not a member of
  • Resource requires higher role than token has

Solution:

  • Request promotion from cluster OWNER/ADMIN
  • Use token with appropriate permissions
  • Verify you're accessing correct cluster

Token Management

Listing Tokens

View all your active tokens:

http
GET /api/v1/account/tokens
Authorization: Bearer <token>

Response:

json
{
  "tokens": [
    {
      "id": "tok_abc123",
      "name": "Production API",
      "createdAt": "2024-01-15T10:30:00Z",
      "lastUsedAt": "2024-01-20T14:22:11Z",
      "expiresAt": null
    },
    {
      "id": "tok_def456",
      "name": "Development",
      "createdAt": "2024-01-10T08:00:00Z",
      "lastUsedAt": "2024-01-19T16:45:32Z",
      "expiresAt": "2024-12-31T23:59:59Z"
    }
  ]
}

Revoking Tokens

Delete a token immediately:

http
DELETE /api/v1/account/tokens/{tokenId}
Authorization: Bearer <token>

Immediate Effect

Revoked tokens stop working immediately. Update any services using the token.

Token Rotation

Best practice: Rotate tokens periodically

  1. Create new token with same permissions
  2. Update applications to use new token
  3. Test new token works
  4. Revoke old token
  5. Monitor for errors

WebSocket Authentication

Agent WebSocket connections use a different flow:

Initial Handshake

typescript
// Connect to WebSocket
const ws = new WebSocket('wss://api.arcadiumpanel.com/ws/agent');

// Send auth message
ws.send(JSON.stringify({
  event: 'auth',
  data: {
    token: 'agent_token_xyz...',
    machineId: 'mch_123',
    version: '0.4.18'
  }
}));

// Wait for auth response
ws.on('message', (data) => {
  const msg = JSON.parse(data);
  if (msg.event === 'authenticated') {
    console.log('Connected!');
  }
});

Auth Events

Client → Server:

json
{
  "event": "auth",
  "data": {
    "token": "agent_token_...",
    "machineId": "mch_123",
    "version": "0.4.18"
  }
}

Server → Client (Success):

json
{
  "event": "authenticated",
  "data": {
    "machineId": "mch_123",
    "clusterId": "clu_abc"
  }
}

Server → Client (Failure):

json
{
  "event": "error",
  "data": {
    "code": "AUTH_FAILED",
    "message": "Invalid agent token"
  }
}

Security Best Practices

Token Storage

Never Commit Tokens

Do not store tokens in version control. Use environment variables or secrets management.

Recommended:

bash
# .env (gitignored)
ARCADIUM_API_TOKEN=arcadium_live_...
javascript
// Load from environment
const token = process.env.ARCADIUM_API_TOKEN;

Avoid:

javascript
// ❌ Hardcoded token
const token = 'arcadium_live_abc123xyz...';

Token Naming

Use descriptive names indicating purpose and environment:

✅ Good:

  • Production API - CI/CD
  • Development - Local Testing
  • Monitoring Integration - Datadog

❌ Bad:

  • Token 1
  • test
  • my-token

Least Privilege

Create tokens with minimum required permissions:

  • Monitoring scripts → VIEWER role
  • Backup automation → ADMIN role (read servers + backups)
  • Full management → ADMIN role

Expiration

Set expiration dates for:

  • Temporary integrations
  • Development/testing tokens
  • Third-party tool access

No expiration only for:

  • Production services
  • Long-term automation

Monitoring

Track token usage in Account Settings:

  • Last Used - Detect unused/abandoned tokens
  • Activity - Unusual usage patterns
  • Revoke - Remove unused tokens

Rate Limiting

API enforces rate limits per token:

TierRequests/MinuteBurst
Free6010
Pro30050
Enterprise1000100

Rate Limit Headers

http
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1641823200

429 Too Many Requests

json
{
  "statusCode": 429,
  "message": "Rate limit exceeded",
  "error": "Too many requests, retry after 30 seconds",
  "retryAfter": 30
}

Handling:

javascript
if (response.status === 429) {
  const retryAfter = response.headers.get('Retry-After');
  await sleep(retryAfter * 1000);
  // Retry request
}

API Base URLs

Production

REST API: https://api.arcadiumpanel.com
WebSocket: wss://api.arcadiumpanel.com/ws

Self-Hosted

REST API: https://your-domain.com/api
WebSocket: wss://your-domain.com/ws

Next Steps

Released under the MIT License.