Skip to main content

🧑‍💻 API Documentation

AtomicHost User API

The AtomicHost User API lets you manage your own game services programmatically — the same services you can manage in the web panel, with the same permissions.

  • Base URL: https://atomichost.xyz/api/client/v1
  • Auth: Bearer API key (one active key per account)
  • Format: JSON request/response (Accept: application/json)
  • Credits: every request costs credits from a daily allowance (default 2,500/day)

This is separate from the admin "application" API at /api/v1.


1. Getting an API key

Generate, view, regenerate or revoke your key from Account → Settings → API Access.

  • You may have one active key at a time.
  • The full key is shown once, immediately after generation. Store it securely.
  • Regenerating immediately invalidates the previous key.
  • Keys look like ah_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
  • We store only a salted SHA‑256 hash of the key — it cannot be recovered if lost.

Authenticating

Send the key as a Bearer token:

Authorization: Bearer ah_your_key_here
Accept: application/json

Every authenticated request is validated server-side for: a valid/active key, an existing non-banned account, ownership/permission of the target service, and rate/credit limits.


2. Credits & rate limiting

Two independent protections apply:

Protection Default Exceeded response
Daily credits 2,500/day (admin-configurable per user) 429 daily_credit_limit_reached
Per-key rate limit 120 requests/minute 429 rate_limited
  • 1 credit = 1 request by default. Opening a console stream costs 5 credits; reading/sending on an open stream costs nothing extra.
  • Credits reset once per day in the server's configured timezone.
  • Failed requests caused by a server-side (5xx) error are refunded.

Every response includes these headers:

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 119
X-Credits-Limit: 2500
X-Credits-Used: 12
X-Credits-Remaining: 2488
X-Credits-Reset: 2026-06-28T00:00:00+00:00

3. Response & error format

Success:

{ "success": true, "data": { ... } }

Error:

{ "success": false, "error": { "code": "forbidden", "message": "..." } }
Status Meaning
200 / 201 OK
401 Missing / invalid / revoked / expired key
403 Banned account, or no permission for this service/action
404 Service not found or not yours (existence is never leaked)
422 Validation error (e.g. bad path, invalid signal)
429 Rate limit or daily credits exhausted
502 The service backend could not be reached

Common error codes: missing_token, invalid_key, account_banned, insufficient_service_permission, feature_unavailable, service_inactive, not_found, validation_failed, rate_limited, daily_credit_limit_reached, too_many_streams, backend_unavailable.


4. Permission model

The API never grants more than the website. For every service action we re-check, server-side:

  1. You are the owner, an admin, or a member that the owner granted the matching permission (console, files, backups, …).
  2. The service is active and your package enables that feature.

If you were given access to someone else's service, the API only allows what that owner granted you on that service. IDs in the request are never trusted — changing a service ID to one that isn't yours returns 404.


5. Endpoints

Account

GET /me

Returns the key owner and current credit standing.

curl https://atomichost.xyz/api/client/v1/me \
  -H "Authorization: Bearer ah_your_key" -H "Accept: application/json"
{
  "success": true,
  "data": {
    "user": { "id": 42, "username": "steve", "email": "[email protected]" },
    "api_key": { "name": "My Key", "prefix": "ah_ab12cd34", "created_at": "2026-06-27T10:00:00+00:00", "last_used_at": "2026-06-27T12:00:00+00:00" },
    "credits": { "limit": 2500, "used": 12, "remaining": 2488, "reset_at": "2026-06-28T00:00:00+00:00", "reset_timezone": "UTC" }
  }
}

Services

GET /servers

List every service you can access (owned + shared with you).

{ "success": true, "data": [
  { "id": 101, "name": "My Rust Server", "status": "active", "service": "pterodactyl",
    "package": { "id": 5, "name": "Rust 4GB" }, "role": "owner",
    "created_at": "2026-06-01T00:00:00+00:00", "due_date": "2026-07-01T00:00:00+00:00" }
] }

GET /servers/{id}

View a single service. (Relationship required.)

GET /servers/{id}/status

Live power state and resource usage.

{ "success": true, "data": {
  "id": 101, "state": "running", "is_suspended": false,
  "resources": { "memory_bytes": 1073741824, "cpu_absolute": 42.5, "disk_bytes": 5368709120 }
} }

POST /servers/{id}/power

Send a power signal. Requires the console permission.

Body: { "signal": "start" } — one of start, stop, restart, kill.

{ "success": true, "data": { "signal": "start", "accepted": true } }

Console (requires the console permission)

POST /servers/{id}/console/command

Send a single console command. Audited.

Body: { "command": "say hello" }

{ "success": true, "data": { "sent": true } }

GET /servers/{id}/console/stream — live output (SSE)

Opens a Server-Sent Events stream that relays live console output. Costs 5 credits to open.

  • The connection is server-controlled: if you are banned or lose access, the stream is closed within ~15s. It also auto-closes after a max duration (default 10 min) — reconnect to continue.
  • Up to 3 concurrent streams per account.

SSE events: ready, output (a console line), status (power state), stats (resource JSON), error, closed.

const es = new EventSource(
  "https://atomichost.xyz/api/client/v1/servers/101/console/stream",
  // EventSource can't set headers; use a proxy/fetch-stream, or a browser
  // extension that adds the Authorization header. See note below.
);
es.addEventListener("output", e => console.log(e.data));
es.addEventListener("closed", e => es.close());

Browsers' native EventSource cannot set an Authorization header. Consume the stream from a server, a CLI (curl -N -H "Authorization: Bearer …"), or a fetch() reader. Commands are sent over the separate console/command endpoint.

curl -N https://atomichost.xyz/api/client/v1/servers/101/console/stream \
  -H "Authorization: Bearer ah_your_key"

Files (requires the files permission)

All paths are validated against directory traversal; .. segments are rejected with 422 before any backend call.

Method Path Body / Query
GET /servers/{id}/files?path=/ list a directory
GET /servers/{id}/files/contents?path=/server.properties read a file
POST /servers/{id}/files/write { "path": "/a.txt", "content": "..." }
POST /servers/{id}/files/delete { "root": "/", "files": ["a.txt"] }
POST /servers/{id}/files/create-folder { "root": "/", "name": "plugins" }
PUT /servers/{id}/files/rename { "root": "/", "from": "a.txt", "to": "b.txt" }
GET /servers/{id}/files/download?path=/world.zip returns a one-time download URL
GET /servers/{id}/files/upload-url?path=/ returns a one-time upload URL
curl "https://atomichost.xyz/api/client/v1/servers/101/files?path=/" \
  -H "Authorization: Bearer ah_your_key" -H "Accept: application/json"
{ "success": true, "data": { "path": "/", "files": [
  { "name": "server.properties", "size": 1234, "is_file": true, "mode": "rw-r--r--" }
] } }

Backups (requires the backups permission)

Method Path Body
GET /servers/{id}/backups list backups
POST /servers/{id}/backups { "name": "pre-update", "ignored": "" }
GET /servers/{id}/backups/{backup} view a backup
DELETE /servers/{id}/backups/{backup} delete a backup
curl -X POST https://atomichost.xyz/api/client/v1/servers/101/backups \
  -H "Authorization: Bearer ah_your_key" -H "Accept: application/json" \
  -d '{"name":"pre-update"}'
{ "success": true, "data": { "backup": { "uuid": "f3...", "name": "pre-update", "is_locked": false } } }

6. Banned / suspended accounts

If your account is banned or suspended, all API keys are revoked immediately, in-flight console streams are closed, and further requests are rejected (403). Unbanning does not restore the old key — generate a new one.