# Falix Public API — full documentation Base URL: `https://client.falixnodes.net/api/v2`. Exact request/response schemas: `https://client.falixnodes.net/api/v2/openapi.json`. The Falix Public API lets developers build tools, automations, and integrations around their Falix servers and account. ## Make a Request 1. Create an API key in the dashboard under **Account → API Keys** and copy the `flx_live_...` secret — it is shown exactly once. 2. Send it as a Bearer token against the `https://client.falixnodes.net/api/v2` base URL. `GET /me` verifies the key and shows what it can do: ```bash curl https://client.falixnodes.net/api/v2/me \ -H "Authorization: Bearer flx_live_..." ``` ```javascript const res = await fetch("https://client.falixnodes.net/api/v2/me", { headers: { Authorization: `Bearer ${process.env.FALIX_API_KEY}` }, }); const { data } = await res.json(); console.log(data.account.username, data.key.scopes); ``` 3. Every success response wraps its payload in a top-level `data` field: ```json { "data": { "account": { "object": "account", "id": 42, "username": "example_user" }, "key": { "object": "api_key", "scopes": ["servers:read"] } } } ``` The full browsable reference — with generated request samples in JavaScript, Python, PHP, and Go, and an in-browser request runner — lives at . Building with an AI assistant? Point it at `https://client.falixnodes.net/api/v2/llms.txt` (concise index) or `llms-full.txt` (the complete documentation as one markdown file). ## Version Policy `/api/v2` is the current stable public API. Breaking changes ship under a new major path such as `/api/v3`; the v2 contract stays compatible for existing integrations. We treat new endpoints, new optional request fields, new response fields, new enum values, and new error codes as additive changes. Clients should ignore fields they do not understand and handle unknown enum values gracefully. Deprecated endpoints or fields are documented before removal and remain available for the rest of the current major version unless a security, abuse, or legal issue requires faster action. ## Responses and Objects Successful responses return JSON with a top-level `data` field. Resource objects include an `object` field, such as `server` or `server_allocation`, so clients can identify records consistently in logs and SDKs. The object reference is generated from the same response schemas used by the endpoints. Each object documents its fields, stable object value, and the endpoints that return or update it. Timestamps are ISO 8601 UTC with second precision (for example `2026-07-04T12:00:00Z`). Optional fields are omitted when empty — treat a missing field as null. ### Conventions - Collection paths are plural (`/servers`, `/backups`); singleton settings are singular (`/firewall`, `/startup`). - Creating a resource returns `201` with the created object. Operations that start background work return `202` — poll the referenced job or status endpoint (see Jobs). - `PATCH` applies a partial update; `PUT` replaces a resource or sets a singleton value (for example a primary allocation). - List endpoints take `limit`/`offset` (see Pagination); `search` is the canonical text-filter parameter. Endpoints that proxy an upstream catalog (addon search, world maps, git commits) page with the provider's `page` parameter instead and say so in their descriptions. - `GET /health` is an unauthenticated liveness probe for monitors and deploy pipelines. ## Pagination Paginated list endpoints accept `limit` (default 25, maximum 100) and `offset` query parameters, and return a `pagination` object alongside `data`: ```json { "data": ["..."], "pagination": { "total": 124, "limit": 25, "offset": 0, "has_more": true } } ``` `limit` and `offset` echo the applied (clamped) values. To walk a full collection, advance `offset` by `limit` until `has_more` is `false`: ```bash curl "https://client.falixnodes.net/api/v2/me/activity?limit=100&offset=200" \ -H "Authorization: Bearer flx_live_..." ``` ## Errors and Request IDs Errors return `error.code`, `error.message`, and a `request_id` that matches the `x-request-id` response header — include it when contacting support. Error examples are status-specific; a 403 shows an authorization error, not a generic authentication error. `error.doc_url` links to the documentation anchor for the specific code. Validation failures may include a field-level `error.errors` array with `field` and `message` entries. Some errors include an `error.action_url` — a link that must be opened in a browser to unblock the action (for example `ad_required` on free-plan power actions). Unknown routes and unsupported methods return the same envelope (`not_found`, `method_not_allowed`), so every error you receive has one shape. ## Error Codes Every error carries a stable machine-readable `error.code`. Match on the code, not the message — messages may be reworded, codes never change meaning. | Code | Status | When it happens | | --- | --- | --- | | `bad_request` | 400 | The request body, query parameters, or content type are invalid. | | `unauthorized` | 401 | The API key is missing, malformed, revoked, expired, blocked by an IP allowlist, or the account is suspended. | | `insufficient_funds` | 402 | The billing balance cannot cover the purchase. Carries a `payment` object with checkout, top-up, and quote URLs so the flow stays programmatic. | | `free_plan_restricted` | 402 | The action is not available on the free plan. | | `forbidden` | 403 | The key lacks a required scope, or the account lacks access to the resource or feature. | | `server_suspended` | 403 | The target server is suspended. | | `ad_required` | 403 | Starting a free-plan server requires watching an ad first. Open `error.action_url` in a browser, then retry within 5 minutes. | | `not_found` | 404 | The resource or endpoint does not exist or is not visible to the caller. | | `method_not_allowed` | 405 | The HTTP method is not supported on this endpoint. | | `conflict` | 409 | The request conflicts with the current state of the resource. | | `limit_reached` | 409 | A plan or per-resource count limit was reached. | | `idempotency_conflict` | 409 | An `Idempotency-Key` was reused with a different request, or the original request is still in flight. | | `server_installing` | 409 | The server is still installing; retry once installation completes. | | `server_transferring` | 409 | The server is transferring between nodes; retry once the transfer completes. | | `server_storage_mode` | 409 | The server is in storage mode and must be started from the console before this feature is available. | | `integration_not_connected` | 412 | A required third-party integration (git provider, Google Drive) is not connected to the account. Check `GET /account/integrations`. | | `payload_too_large` | 413 | The request body exceeds the endpoint's documented size limit. | | `validation_failed` | 422 | One or more request fields failed validation. Carries a field-level `error.errors` array with `field` and `message` entries. | | `unprocessable_entity` | 422 | The request is syntactically valid but cannot be processed in its current form. | | `rate_limit_exceeded` | 429 | The key's per-minute rate limit was exceeded. Back off until the window resets; `Retry-After` carries the wait in seconds. | | `request_error` | 4xx | A request-level error without a more specific code. | | `internal_error` | 500 | An unexpected server error occurred. Include the `request_id` when contacting support. | | `upstream_error` | 502 | The server's node rejected or failed the request. | | `service_unavailable` | 503 | A required backing service is temporarily unavailable. Safe to retry with backoff. | | `upstream_timeout` | 504 | The server's node did not respond in time. Safe to retry with backoff. | ## Rate Limits Every API key has a per-minute request limit (default 60, configurable per key up to 10000). Responses include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (unix seconds) headers. When the limit is exceeded the API returns `429 rate_limit_exceeded` with a `Retry-After` header — back off until the window resets. ### Retries - On `429`, wait the number of seconds in `Retry-After`, then retry. - On `5xx` (`internal_error`, `upstream_error`, `upstream_timeout`, `service_unavailable`), retry with exponential backoff and jitter (for example 1s, 2s, 4s, capped at 30s). - When retrying a mutation, reuse the same `Idempotency-Key` so a retry can never apply twice — see Idempotency below. - Client errors (`4xx` other than `429`) are not retryable: fix the request instead. ## Idempotency Mutating operations document an optional `Idempotency-Key` header. Use a unique printable-ASCII value of at most 200 characters, and reuse it only for retries of the same request. Successful and server-error responses remain replayable for 24 hours and include `Idempotency-Replayed: true` when served from the idempotency store. Caching 5xx responses is deliberate: an upstream system may accept a mutation before a later step reports a failure, so re-executing the same request would be unsafe. Client-error responses release the key. Replay bodies are encrypted before they enter the idempotency store because mutation responses can contain short-lived credentials or signed URLs. If the store or encryption key is unavailable, the API fails a keyed request before executing it. An in-flight claim uses a renewable six-minute lease. Long operations renew it while they run; if an API process crashes, the abandoned claim expires instead of blocking the key forever. Large request bodies are supported up to the limit documented by each operation. Reusing a key for a different path, query, or body fails with `409 idempotency_conflict`, as does retrying while the original request is still in flight. Only successful 2xx responses are replayed. These guarantees require the idempotency store to remain available; requests fail closed when a claim cannot be established. ## Jobs Operations that take longer than a request cycle return `202 Accepted` instead of the finished result, and their descriptions say where to follow progress: - Job-backed operations (server creation, modpack installs, clones, module tasks) return a job object — an `object` value ending in `_job`, a `job_id`, and a `state` of `queued`, `running`, `completed`, `partial`, `failed`, or `timed_out`, plus `progress`, `message`, and any `warnings` or `errors`. Poll the matching `GET .../jobs/{job_id}` endpoint until the state is terminal. - State-backed operations poll a status resource instead: backup restores and reinstalls surface through `lifecycle_status` on `GET /servers/{server_id}/status`, server transfers through `GET /servers/{server_id}/settings/transfer/status`, file pulls through `GET .../files/pull/status`. - Power signals and console commands are acknowledged with `202` and observed live over the WebSocket. Starting a job requires the area's write scope; polling requires only its read scope. ## Webhooks Register per-server HTTPS webhooks with `POST /servers/{server_id}/hooks` (scope `servers:webhooks:write`) to receive server events without polling. Subscriptions are per event type: - Lifecycle: `server.installed`, `server.started`, `server.stopped`, `server.crashed`, `server.idle` - Activity: `backup.completed`, `player.joined`, `player.left`, `git.deployment.completed` - Resource alerts: `threshold.cpu`, `threshold.memory`, `threshold.disk` The signing `secret` is returned once, in the creation response — store it like a password. High-frequency events (`player.*`, `threshold.*`) only deliver when explicitly subscribed. ### Delivery format Each event is delivered as a `POST` to your URL with `Content-Type: application/json` and two headers: - `X-Falix-Event` — the event type, for example `server.started`. - `X-Falix-Signature` — `sha256=`: an HMAC-SHA256 of the exact request body, computed with your webhook secret. The body has the same shape for every event: ```json { "event": "server.started", "server": { "id": 123 }, "occurred_at": 1752300000, "data": {} } ``` `occurred_at` is unix seconds. `data` carries event-specific context and may be empty — treat unknown fields as additive, like everywhere else in the API. ### Verifying signatures Recompute the HMAC over the raw request bytes — before any JSON parsing or re-serialization — and compare it to the header value with a constant-time comparison: ```python import hashlib, hmac def verify(secret: str, body: bytes, signature_header: str) -> bool: expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature_header) ``` Reject deliveries whose signature does not match: anyone can discover your endpoint URL, but only Falix holds the secret. ### Delivery policy - A delivery counts as successful on any `2xx` response. Respond quickly — the request times out after 5 seconds — and do heavy processing asynchronously. - Redirects are not followed; the webhook URL must answer directly over HTTPS. - Failed deliveries are retried a bounded number of times. After 15 consecutive failures the webhook is disabled automatically; re-enable it with `PATCH /servers/{server_id}/hooks/{hook_id}` (`{"enabled": true}`), which also clears the failure counter. - Inspect recent attempts and their outcomes with `GET /servers/{server_id}/hooks/{hook_id}/deliveries`. ## Integrations Some endpoints use third-party integrations connected to your Falix account: git providers (repository access, deployments) and Google Drive (off-site backups). Connecting or disconnecting an integration is an interactive OAuth flow and is only available in the dashboard — the API operates on integrations that are already linked. Calling an integration-backed endpoint without the required link fails with `412 integration_not_connected`. Check `GET /account/integrations` (scope `account:integrations:read`) to see what is connected before calling. ## Access API keys are scoped, rate limited, revocable, and can be restricted to specific IP addresses. A key can only access servers the owning Falix account can access. Public endpoints intentionally avoid exposing secrets, credentials, or other users' personal data. Keep API keys on trusted servers. Do not put them in browser code, public repositories, mobile apps, or game plugins shipped to users. ## Scopes Every API key carries an explicit list of scopes. Requests outside the granted scopes fail with `403 forbidden`. | Scope | Access | Description | | --- | --- | --- | | `*` | Read & write | Grants every scope, including destructive actions. Use only for trusted automation. | | `servers:*` | Read & write | Grants every servers:* scope except destructive actions, which must be granted explicitly. | | `servers:read` | Read-only | List servers, read server details, and read live status. | | `servers:command` | Read & write | Send individual console commands to a server. | | `servers:console` | Read & write | Issue short-lived WebSocket tokens for live console access. | | `servers:power` | Read & write | Start, stop, restart, and kill servers. | | `servers:reinstall` | Read & write | Reinstall a server, optionally wiping its files first. Destructive: never granted by the `servers:*` wildcard and must be granted explicitly. | | `servers:delete` | Read & write | Permanently delete a server. Irreversible and owner-only: never granted by the `servers:*` wildcard and must be granted explicitly. | | `servers:create` | Read & write | Create new servers on the account. Consumes plan quota and, for paid plans, charges the billing balance: never granted by the `servers:*` wildcard and must be granted explicitly. | | `applications:read` | Read-only | List the deployable application catalog (games, software, databases) with slugs and free-tier availability. | | `templates:read` | Read-only | List and read the account's saved FalixInit templates, and dry-run validate manifests. | | `templates:write` | Read & write | Create, update, and delete the account's saved FalixInit templates. | | `servers:webhooks:read` | Read-only | List a server's lifecycle webhooks and their delivery state. | | `servers:webhooks:write` | Read & write | Register, update, and delete server lifecycle webhooks. | | `servers:activity:read` | Read-only | Read sanitized server activity events. | | `servers:network:read` | Read-only | List server allocations and connection addresses. | | `servers:network:write` | Read & write | Create, update, and delete server allocations. | | `servers:databases:read` | Read-only | List server databases and read connection details. | | `servers:databases:write` | Read & write | Create and delete server databases and rotate passwords. | | `servers:files:read` | Read-only | List directories, read file content, search files, and generate download URLs. | | `servers:files:write` | Read & write | Write, create, rename, copy, move, delete, compress, and upload files. | | `servers:backups:read` | Read-only | List and inspect server backups and generate backup download URLs. | | `servers:backups:write` | Read & write | Create, delete, lock, and unlock server backups. | | `servers:backups:restore` | Read & write | Restore a server from a backup. Destructive: never granted by the `servers:*` wildcard and must be granted explicitly. | | `servers:properties:read` | Read-only | Read a server's server.properties entries. | | `servers:properties:write` | Read & write | Update a server's server.properties entries. | | `servers:settings:read` | Read-only | Read a server's name, description, done message, and stop command. | | `servers:settings:write` | Read & write | Update a server's name, description, done message, and stop command. | | `servers:startup:read` | Read-only | Read a server's startup command, docker image, egg, and environment variables. | | `servers:startup:write` | Read & write | Update a server's startup command and environment variables. | | `servers:proxies:read` | Read-only | List a server's HTTP proxies, their SSL state, and limits. | | `servers:proxies:write` | Read & write | Create, update, delete, and re-issue SSL for HTTP proxies. | | `servers:schedules:read` | Read-only | List schedules, read schedule details, and read execution logs. | | `servers:schedules:write` | Read & write | Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. | | `servers:domains:read` | Read-only | List a server's custom domains and their verification state. | | `servers:domains:write` | Read & write | Add, verify, re-point, and remove customer-owned domains. | | `servers:sftp:read` | Read-only | Read a server's SFTP hostname, port, and username. No password is ever returned. | | `servers:subdomains:read` | Read-only | List a server's managed subdomains and available suffixes. | | `servers:subdomains:write` | Read & write | Create, rename, re-point, and delete managed subdomains. | | `servers:worlds:read` | Read-only | List a server's worlds, search marketplace maps, and generate world download URLs. | | `servers:worlds:write` | Read & write | Set the primary world and install maps and Bedrock .mcworld files. | | `servers:players:read` | Read-only | List players, read player detail, query online players, read max-players, and preview UUID migrations. | | `servers:players:write` | Read & write | Send player commands, edit player NBT, set max-players, delete player files, and apply UUID migrations. | | `servers:addons:read` | Read-only | List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. | | `servers:addons:write` | Read & write | Install and toggle addons, install modpacks, and create, edit, and install custom packs. | | `servers:subusers:read` | Read-only | List users with delegated access to a server and their permissions. | | `servers:subusers:write` | Read & write | Add, update, and remove subusers. Grants access on your behalf: never granted by the `servers:*` wildcard and must be granted explicitly. | | `servers:git:read` | Read-only | Read linked repository status, branches, commits, file trees, and deployment history. | | `servers:git:write` | Read & write | Link and unlink repositories, edit git settings, and manage deploy-triggered schedules. | | `servers:git:deploy` | Read & write | Deploy repository contents onto the server, replacing files and running post-deploy commands. Never granted by wildcards and must be granted explicitly. | | `servers:firewall:read` | Read-only | Read firewall rules, state, and traffic analytics. | | `servers:firewall:write` | Read & write | Add, update, toggle, and delete firewall rules and sync them to the node. | | `servers:monitor:read` | Read-only | Read health scores, resource monitoring data, crash history, and player-activity analytics. | | `servers:logs:read` | Read-only | Run log analysis and pattern detection over server logs. | | `servers:logs:write` | Read & write | Create public shared-log links for a server's logs. | | `servers:modules:read` | Read-only | List installed runtime dependency modules, search the registry, and read module tasks. | | `servers:modules:write` | Read & write | Install, update, and remove runtime dependency modules. | | `servers:importer:write` | Read & write | Import an external server, replacing the current server's files. Destructive and never granted by wildcards: must be granted explicitly. | | `servers:instances:read` | Read-only | List a server's instances and clone jobs. | | `servers:instances:write` | Read & write | Create, update, activate, and clone server instances. | | `servers:instances:delete` | Read & write | Permanently delete a server instance. Irreversible and never granted by wildcards: must be granted explicitly. | | `servers:advertisement:read` | Read-only | Read a server's public listing, posts, and comments. | | `servers:advertisement:write` | Read & write | Publish and edit a server's public listing, posts, and moderate its comments. | | `servers:support-access:read` | Read-only | Read whether Falix staff currently hold time-boxed access to a server. | | `servers:support-access:write` | Read & write | Grant and revoke time-boxed Falix staff access to a server. Opens the server to staff: never granted by wildcards and must be granted explicitly. | | `account:tickets:read` | Read-only | List and read the account's support tickets and their message threads. | | `account:tickets:write` | Read & write | Open, reply to, rename, close, and reopen the account's support tickets. | | `utility:mcquery` | Read-only | Query the status of any public Minecraft server by address. | | `account:ssh-keys:read` | Read-only | List the SSH public keys registered on the account. | | `account:ssh-keys:write` | Read & write | Add and remove account SSH keys. Grants SFTP/SSH access to every server on the account: never granted by wildcards and must be granted explicitly. | | `account:integrations:read` | Read-only | Read which third-party integrations (git providers, Google Drive) are connected to the account. | | `account:billing:read` | Read-only | Read the subscription overview, balances, billing documents, and resource pricing. Never exposes payment methods or payment links. | | `account:billing:write` | Read & write | Create hosted checkout sessions that add funds to the billing balance. Initiates payments: never granted by wildcards and must be granted explicitly. | Destructive scopes (server deletion, reinstall, backup restore) are never granted by `servers:*` — they must be granted individually or via the global `*` scope. ## Changelog ### 2026-07-11 🎉 **Falix API v2 is live!** Manage your servers and account through one consistent, documented API — servers, files, backups, networking, content, automation, insights, billing, and support. Create an API key in the dashboard (Account → API Keys) and start exploring. New capabilities ship regularly and are always additive — see the version policy above. # Endpoints ## Docs ### GET /docs — Get public API documentation. Permanently redirects to the hosted API reference. No authentication required. The machine-readable spec stays at `GET /openapi.json`. Responses: `308` Redirect to the hosted API reference ### GET /llms-full.txt — Get the full LLM documentation The complete public API documentation — every guide section and every operation with its parameters and responses — as one markdown document (the llms-full.txt convention). Paste it into an AI assistant's context or point a retrieval pipeline at it. No authentication required. Responses: `200` Full markdown documentation for LLMs ### GET /llms.txt — Get the LLM documentation index A concise markdown orientation for AI assistants (the llms.txt convention): what the API is, how auth and responses work, and one line per endpoint linking into the reference. No authentication required. Responses: `200` Markdown index for LLMs ### GET /openapi.json — Get public OpenAPI JSON specification. Returns the OpenAPI document this reference is generated from, for SDK generators and API tooling. No authentication required. Responses: `200` OpenAPI JSON specification ## Health ### GET /health — Check API health Unauthenticated liveness probe. Returns a static body whenever the API process is serving requests; it touches no database or cache, so it is safe to poll aggressively from monitors and deploy pipelines. Responses: `200` API is serving requests ## Account ### GET /account/integrations — Get third-party integration status Returns which git providers and Google Drive are connected to the account. Only connection status (and, for git, the provider username) is returned — never OAuth tokens or the linked Google email. Use this to detect the not-connected state before calling git or Google Drive endpoints. **Access** Account-level; no server permission applies. Responses: `200` Integration connection status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Integrations service unavailable ### GET /me — Get the current account Verifies an API key and returns the account plus non-secret key metadata: name, prefix, scopes, rate limit, creation time, expiry, and last use. Use this endpoint for setup checks in CLIs, deployment jobs, and backend integrations. **Access** Any valid public API key. Responses: `200` Current account; `401` Authentication: Invalid or missing API key; `429` Rate limited ## SSH Keys ### GET /account/ssh-keys — List account SSH keys Returns the SSH public keys registered on the account. Only the public key and its fingerprint are returned — no private key material is ever stored. **Access** Account-level; no server permission applies. Parameters: - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Account SSH keys; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: SSH key service unavailable ### POST /account/ssh-keys — Add an account SSH key Registers an SSH public key on the account. The key is validated, a SHA-256 fingerprint is computed, and duplicate fingerprints are rejected. The key then grants SFTP/SSH access to every server on the account, so this endpoint requires the dangerous `account:ssh-keys:write` scope (never granted by a wildcard). Unlike the dashboard, no 2FA code is required — the dangerous scope replaces that step. **Access** Dangerous scope: grants SFTP/SSH access to every server on the account. Never granted by a wildcard. Parameters: - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` SSH key added; `400` Bad request: Invalid key format or name; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or restricted account; `409` Conflict: A key with this fingerprint already exists; `429` Rate limited; `503` Service unavailable: SSH key service unavailable ### DELETE /account/ssh-keys/{key_id} — Remove an account SSH key Removes an SSH key from the account by id. The key must belong to the acting account. Requires the dangerous `account:ssh-keys:write` scope; no 2FA code is required (the dangerous scope replaces that step). **Access** Dangerous scope; never granted by a wildcard. Parameters: - `key_id` (path, required): SSH key id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` SSH key removed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `404` Not found: SSH key not found; `429` Rate limited; `503` Service unavailable: SSH key service unavailable ## Applications ### GET /applications — List applications Returns the catalog of deployable applications (games, software runtimes, and databases) for building a create-server dropdown. The catalog is small and static, so the response is not paginated. Use the optional `kind` and `free_tier` query parameters to narrow the list. **Access** API scope: `applications:read` — List the deployable application catalog (games, software, databases) with slugs and free-tier availability.. Parameters: - `kind` (query): Filter by application kind: `game`, `application`, or `database`. Omit to return every kind. - `free_tier` (query): Filter by free-plan availability. When `true`, only applications that can be deployed on the free plan are returned; when `false`, only those that require a paid plan. Omit to return both. Responses: `200` Application catalog; `400` Bad request: Invalid filter value; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited ## Servers ### GET /account/servers/create-jobs/{job_id} — Retrieve a server-creation job Polling endpoint for `POST /servers`: reports provisioning progress until the job is `ready` or `failed`. **Access** API scope: `servers:read` — List servers, read server details, and read live status.. Parameters: - `job_id` (path, required): Creation job id Responses: `200` Creation job; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `404` Not found: Job not found; `429` Rate limited; `503` Service unavailable: Server service unavailable ### GET /servers — List servers Returns the servers the API key can access, paginated and ordered by name. `search` filters by name substring. `include=status` adds each server's live status (state and resource usage) to the page; live status is fetched from the nodes with bounded concurrency and only for servers whose console the key's user may access. **Access** API scope: `servers:read` — List servers, read server details, and read live status.. Parameters: - `limit` (query): Maximum number of servers to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of servers to skip. Defaults to `0`. - `search` (query): Case-insensitive server-name filter. - `include` (query): Set to `status` to include each server's live status in the page. Adds one node round-trip per running server, so use it only when the live state is actually needed. Responses: `200` Visible servers; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited ### POST /servers — Create a server Creates a server asynchronously for free or paid plans and returns a creation job to poll. Free plans have platform-assigned resources and a restricted application list; paid plans are charged to the billing balance up front (`402` with a checkout URL when it cannot cover the price). Supports FalixInit manifests for declarative first-boot provisioning. **Access** Owner-account only. Consumes plan quota and, for paid plans, charges the billing balance; never granted by wildcards. Parameters: - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Creation accepted; poll the job; `400` Bad request: Invalid request; `401` Authentication: Invalid or missing API key; `402` Payment required: Balance cannot cover the price; pay the checkout URL or top up; `403` Authorization: Missing scope, unverified email, or restricted region; `409` Conflict: Creation already in progress or plan limit reached; `422` Validation failed (field errors included); `429` Rate limited; `503` Service unavailable: A required backend service is unavailable ### GET /servers/{server_id} — Get server Returns stable metadata for a single server. **Access** API scope: `servers:read` — List servers, read server details, and read live status.. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server detail; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `404` Not found: Server not found; `429` Rate limited ### DELETE /servers/{server_id} — Delete a server Permanently deletes the server: files on the node, all panel records, and its proxies. Paid time is refunded as account credit. Irreversible: requires the explicit `servers:delete` scope, and only a key belonging to the server owner may call it. The dashboard's 2FA step-up is replaced by the explicit scope grant. **Access** API scope: `servers:delete` — irreversible, never granted by the `servers:*` wildcard; grant it explicitly. Server access: the server owner only. The dashboard's 2FA step-up is replaced by the explicit scope grant. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Server deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Server service unavailable ### POST /servers/{server_id}/reinstall — Reinstall a server Re-runs the server's install script, optionally wiping all files first. Destructive: requires the explicit `servers:reinstall` scope. **Access** API scope: `servers:reinstall` — destructive, never granted by the `servers:*` wildcard; grant it explicitly. Server access: owner, or server permission `file.delete`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Reinstall initiated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node reinstall request failed; `503` Service unavailable: Server service unavailable ### GET /servers/{server_id}/status — Get server status Returns live state and resource usage. Temporary node failures are reported as `node_ready: false` with `state: "offline"`, so polling clients can keep a simple control flow. **Access** API scope: `servers:read` — List servers, read server details, and read live status. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ### GET /servers/{server_id}/status-issues — Check status-page issues for a server's node Checks the public status page for active incidents or scheduled notices matching the server's node, its region, or a global notice. Use this to distinguish a server-side problem from platform maintenance before paging anyone. **Access** API scope: `servers:read` — List servers, read server details, and read live status. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Matching status-page notice, if any; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Status service unavailable ## Webhooks ### GET /servers/{server_id}/hooks — List server webhooks Returns the lifecycle webhooks registered on a server. The signing secret is never returned. **Access** API scope: `servers:webhooks:read` — List a server's lifecycle webhooks and their delivery state. Server access: owner, or server permission `settings.edit`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of webhooks to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of webhooks to skip. Defaults to `0`. Responses: `200` Server webhooks; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Webhook service unavailable ### POST /servers/{server_id}/hooks — Create a server webhook Registers a lifecycle webhook. The URL must be `https` and must not resolve to a private/reserved address. The signing secret is auto-generated when omitted and is returned only in this response — it can never be retrieved again. Deliveries POST a `WebhookEventEnvelope` body signed with `X-Falix-Signature`; see the Webhooks guide for the payload shape and verification steps. **Access** The signing secret is returned only in this create response. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Webhook created (includes the secret); `400` Bad request: Invalid URL, events, or secret; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Webhook limit reached; `429` Rate limited; `503` Service unavailable: Webhook service unavailable ### DELETE /servers/{server_id}/hooks/{hook_id} — Delete a server webhook Removes a lifecycle webhook by id. **Access** API scope: `servers:webhooks:write` — Register, update, and delete server lifecycle webhooks. Server access: owner, or server permission `settings.edit`. Parameters: - `server_id` (path, required): Falix server id - `hook_id` (path, required): Webhook id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Webhook removed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or webhook not found; `429` Rate limited; `503` Service unavailable: Webhook service unavailable ### PATCH /servers/{server_id}/hooks/{hook_id} — Update a server webhook Updates any subset of a webhook's URL, subscribed events, and enabled flag. A changed URL is re-vetted (`https`-only). Re-enabling a webhook clears its failure counter. **Access** API scope: `servers:webhooks:write` — Register, update, and delete server lifecycle webhooks. Server access: owner, or server permission `settings.edit`. Parameters: - `server_id` (path, required): Falix server id - `hook_id` (path, required): Webhook id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Webhook updated; `400` Bad request: Invalid URL or events; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or webhook not found; `429` Rate limited; `503` Service unavailable: Webhook service unavailable ### GET /servers/{server_id}/hooks/{hook_id}/deliveries — List webhook deliveries Returns a webhook's delivery attempts, newest first. **Access** API scope: `servers:webhooks:read` — List a server's lifecycle webhooks and their delivery state. Server access: owner, or server permission `settings.edit`. Parameters: - `server_id` (path, required): Falix server id - `hook_id` (path, required): Webhook id - `limit` (query): Maximum number of deliveries to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of deliveries to skip. Defaults to `0`. Responses: `200` Recent deliveries; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or webhook not found; `429` Rate limited; `503` Service unavailable: Webhook service unavailable ## Console ### POST /servers/{server_id}/commands — Send a console command Sends one command to a server console. Commands are single-line only; batch execution is intentionally not supported by this endpoint. **Access** API scope: `servers:command` — Send individual console commands to a server. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Command accepted; `400` Bad request: Invalid command; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server state does not allow commands; `429` Rate limited; `502` Upstream error: Server node communication error ### POST /servers/{server_id}/console/eula — Accept the Minecraft EULA Writes `eula=true` to the server's `eula.txt`, allowing the server to start. **Access** API scope: `servers:console` — Issue short-lived WebSocket tokens for live console access. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` EULA accepted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node communication error ### GET /servers/{server_id}/console/queue-status — Get startup queue status Returns the server's position in the node startup queue, including status, estimated wait, and boost state. Returns `queued: false` when the server is not currently queued. **Access** API scope: `servers:read` — List servers, read server details, and read live status. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Startup queue status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ### GET /servers/{server_id}/console/status — Get server status Returns the server's live state and, when the node is reachable, its CPU, memory, disk, network, and uptime usage. Falls back to `offline` with `node_ready: false` when the node cannot be reached. **Access** API scope: `servers:read` — List servers, read server details, and read live status. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server status and resources; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ### GET /servers/{server_id}/console/storage — Get storage mode Reports whether the server's node is a storage-only node with limited functionality, matching the console UI's storage banner. **Access** API scope: `servers:read` — List servers, read server details, and read live status. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Storage-mode state; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ### GET /servers/{server_id}/console/timer — Get shutdown timer Returns the server's shutdown or expiry timer. Checks the explicit free-plan expiry timer first, then the inactivity-shutdown timer. `active` is `false` when no timer is set. **Access** API scope: `servers:read`. Server access: owner, or any subuser with access to the server — reading the shutdown timer needs no specific server permission, matching the dashboard. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Shutdown timer; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server access; `404` Not found: Server not found; `429` Rate limited; `500` Server error: Timer lookup failed ## Power ### POST /servers/{server_id}/power — Send a power signal Sends `start`, `stop`, `restart`, or `kill` to the server. Returns `202` with a `power_state` describing what happened: signals are `applied` directly, `queued` when the node uses a startup queue, or `transferring` when a stored server first moves back to a runtime node. Poll `GET /servers/{server_id}/status` to observe the transition. Starting or restarting a free-plan server requires a recent ad view. When none is on record the request fails with `403 ad_required` and `error.action_url` links to a page where the ad can be watched; retry the power action within 5 minutes of watching. **Access** API scope: `servers:power`. Server access: owner, or the control permission matching the signal (`control.start`, `control.stop`, or `control.restart`). Parameters: - `server_id` (path, required): Server ID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Power action accepted; `400` Bad request: Unknown signal; `401` Authentication: Invalid API key; `403` Authorization: Missing scope or server permission, or `ad_required` for free-plan starts (see `error.action_url`); `404` Not found: Server not found; `409` Conflict: Server state conflict or action already in progress; `429` Rate limit exceeded; `503` Service unavailable: Node busy or queue unavailable ## Settings ### GET /servers/{server_id}/resources — Retrieve resource limits Returns the server's CPU, RAM, and disk limits. **Access** API scope: `servers:settings:read` — Read a server's name, description, done message, and stop command. Server access: owner, or server permission `settings.resources`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server resource limits; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ### PUT /servers/{server_id}/resources — Update resource limits Adjusts CPU, RAM, and disk within the owner's plan allowance, with the same premium gating and balance accounting as the dashboard. Billing servers cannot change resources here. **Access** API scope: `servers:settings:write`. Server access: owner, or server permission `settings.resources`. Changing resources requires a premium plan; billing servers manage resources through their subscription. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Resources updated; `400` Bad request: Invalid values or plan limits exceeded; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or premium plan; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Resource service unavailable ### GET /servers/{server_id}/settings — Retrieve server settings Returns the consolidated, cheaply-readable server settings: display name, description, startup-detection message, and stop command. **Access** API scope: `servers:settings:read` — read consolidated server settings. Server access: owner, or server permission `settings.edit`. The dashboard splits these settings across finer-grained read permissions; the consolidated resource gates the whole read on `settings.edit`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server settings; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Settings service unavailable ### PATCH /servers/{server_id}/settings — Update server settings Accepts any subset of the writable settings. Each present field is validated and written exactly as the dashboard does, and enforces the same per-field server permission: `settings.rename` for `name`, `settings.description` for `description`, `settings.edit` for `done_message`, `stop_command`, `timezone`, `auto_stop`, and `start_on_join`, `control.console` for `autoupdate_mode`, `file.update` for the MOTD fields, and `file.read` + `file.update` for `online_mode`. `start_on_join` additionally requires a premium subscription. Returns the updated settings. **Access** API scope: `servers:settings:write`. Server access: owner, or the per-field server permission the dashboard requires — `settings.rename` for `name`, `settings.description` for `description`, `settings.edit` for `done_message`, `stop_command`, `timezone`, `auto_stop`, and `start_on_join`, `control.console` for `autoupdate_mode`, `file.update` for the MOTD fields, and `file.read` + `file.update` for `online_mode`. `start_on_join` also requires a premium subscription. Each field is checked before it is written. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Server settings updated; `400` Bad request: Invalid or empty update body; `401` Authentication: Invalid or missing API key; `402` Payment required: Premium subscription required for the field; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node rejected a `server.properties` read or write; `503` Service unavailable: Settings service unavailable ### PUT /servers/{server_id}/settings/application — Switch the server's software Changes the server software. Provide exactly one of `application` (switch gameType/egg — resets variables and reinstalls), `version` (Java/runtime version key), or `image` (a specific Docker image from the current egg). Each path runs the exact dashboard write and its own permission and free-plan/premium checks. **Access** API scope: `servers:settings:write`. Server access depends on the chosen field: switching `application` (game type) requires `file.delete` and is blocked for free-plan games; `version` and `image` changes require `startup.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Software switched; `400` Bad request: Invalid request or unsupported target; `401` Authentication: Invalid or missing API key; `402` Payment required: Target application is not available on the free plan; `403` Authorization: Missing scope or server permission; `404` Not found: Server or egg not found; `409` Conflict: Server is installing or transferring; `429` Rate limited ### GET /servers/{server_id}/settings/applications — List switchable applications Returns the catalog of applications this server can switch to, grouped by category, with the current application marked. **Access** API scope: `servers:settings:read`. Server access: owner or any subuser of the server; no specific server permission is required to read the catalog. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Application catalog; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Settings service unavailable ### POST /servers/{server_id}/settings/transfer — Transfer the server Moves the server to the best available node in the target region. Mirrors the dashboard's checks: `settings.transfer` permission, transfer-forbidden and premium gates, and a short post-transfer cooldown. Poll `GET /servers/{server_id}/settings/transfer/status` until the state is `completed` or `failed`. **Access** API scope: `servers:settings:write`. Server access: owner, or server permission `settings.transfer`. Transfers can be disabled per-server, region availability and premium plan gate the target node, and a short cooldown blocks back-to-back transfers. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Transfer accepted; `400` Bad request: Invalid region or no viable node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or transfers disabled; `404` Not found: Server not found; `409` Conflict: Server already transferring or recently transferred; `429` Rate limited; `503` Service unavailable: Transfer service unavailable ### GET /servers/{server_id}/settings/transfer/availability — Get transfer availability Returns, per region, whether a node can accept this server given its disk usage. Requires the `settings.transfer` permission. **Access** API scope: `servers:settings:read` — Read a server's name, description, done message, and stop command. Server access: owner, or server permission `settings.transfer`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Transfer availability; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Transfer service unavailable ### GET /servers/{server_id}/settings/transfer/status — Get transfer status Reports the state of the server's most recent transfer, so `POST /servers/{server_id}/settings/transfer` can be followed to completion: `in_progress` until the destination node confirms the move, then `completed` or `failed`. Live migration progress (percentages, log lines) is streamed over the server WebSocket as `transfer status` events. **Access** API scope: `servers:settings:read` — Read a server's name, description, done message, and stop command. Server access: owner, or server permission `settings.transfer`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Latest transfer state; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Transfer service unavailable ## Notifications ### GET /servers/{server_id}/settings/crash-config — Retrieve crash-detection config Returns the server's crash detection and auto-recovery settings. Premium feature. **Access** API scope: `servers:settings:read`. Server access: owner, or server permission `settings.edit`. Requires a premium subscription. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Crash config; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or premium subscription; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node rejected the request ### PUT /servers/{server_id}/settings/crash-config — Update crash-detection config Updates crash detection and auto-recovery settings. Only the provided fields change. Premium feature. **Access** API scope: `servers:settings:write`. Server access: owner, or server permission `settings.edit`. Requires a premium subscription. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Crash config updated; `400` Bad request: Invalid max_crashes or time_window range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or premium subscription; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node rejected the request ### GET /servers/{server_id}/settings/discord-webhook — Retrieve the Discord webhook Returns the configured Discord webhook with a masked URL (the full URL, a secret, is never returned) and its event triggers. **Access** API scope: `servers:settings:read`. Server access: owner, or server permission `settings.edit`. The webhook URL is always masked; the full URL (a secret) is never returned. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Discord webhook configuration; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Settings service unavailable ### PUT /servers/{server_id}/settings/discord-webhook — Set the Discord webhook Validates the URL against the Discord webhook pattern and stores it with the given event triggers. Returns the masked webhook. **Access** API scope: `servers:settings:write`. Server access: owner, or server permission `settings.edit`. The URL must be a `discord.com`/`discordapp.com` webhook URL. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Discord webhook configured; `400` Bad request: Invalid Discord webhook URL; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Settings service unavailable ### DELETE /servers/{server_id}/settings/discord-webhook — Delete the Discord webhook Removes the configured Discord webhook. Returns the resource in its now unconfigured state. **Access** API scope: `servers:settings:write` — Update a server's name, description, done message, and stop command. Server access: owner, or server permission `settings.edit`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Discord webhook removed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Settings service unavailable ### POST /servers/{server_id}/settings/discord-webhook/test — Send a Discord webhook test message Posts a test embed to the configured webhook. Returns `404` when no webhook is configured. **Access** API scope: `servers:settings:write`. Server access: owner, or server permission `settings.edit`. Returns `404` when no webhook is configured. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Test message delivered; `400` Bad request: Discord rejected the webhook; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: No webhook configured; `429` Rate limited; `502` Upstream error: Failed to reach Discord ## Startup ### GET /servers/{server_id}/startup — Retrieve startup configuration Returns the server's startup command, current and available docker images, egg id and default egg startup, and environment variables. **Access** API scope: `servers:startup:read` — Read a server's startup command, docker image, egg, and environment variables. Server access: owner, or server permission `startup.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server startup configuration; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Startup service unavailable ### PATCH /servers/{server_id}/startup — Update startup command Updates the startup command template and syncs the change to the node. Requires a premium subscription and the `startup.update` permission. Docker image and egg changes are dashboard-only and are read-only in this resource. **Access** API scope: `servers:startup:write`. Server access: owner, or server permission `startup.update`. Updating the startup command also requires a premium subscription. Docker image and egg changes are read-only here and must be made from the dashboard. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Startup configuration updated; `400` Bad request: Missing or invalid startup command; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or premium subscription; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Startup service unavailable ### PATCH /servers/{server_id}/startup/variables/{env_variable} — Update an environment variable Sets the value of a single environment variable, identified by its `env_variable` key. The variable must belong to the server's egg. Syncs the change to the node. Requires the `startup.update` permission. **Access** API scope: `servers:startup:write` — Update a server's startup command and environment variables. Server access: owner, or server permission `startup.update`. Parameters: - `server_id` (path, required): Falix server id - `env_variable` (path, required): Environment variable key - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Variable updated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or variable not found; `429` Rate limited; `503` Service unavailable: Startup service unavailable ## Properties ### GET /servers/{server_id}/properties — List server properties Reads `server.properties` from the node and returns every entry as a `server_property` object, sorted by key. **Access** API scope: `servers:properties:read` — Read a server's server.properties entries. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Server properties; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node could not read the properties file ### PUT /servers/{server_id}/properties — Update server properties Writes a bulk set of key/value pairs to `server.properties`. The update is a merge: only the keys you send are changed, and existing comments and ordering are preserved. Free-plan servers have resource-related properties clamped, matching the dashboard. Returns the updated properties. **Access** API scope: `servers:properties:write` — Update a server's server.properties entries. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Server properties updated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node could not read or write the properties file ### GET /servers/{server_id}/properties/configs — List available config files Detects which known application config files (bukkit, spigot, paper, …) exist on the server. `server.properties` is excluded: it has its own `/properties` endpoints. **Access** API scope: `servers:properties:read` — Read a server's server.properties entries. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Detected config files; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node could not list the server files ### GET /servers/{server_id}/properties/configs/{config_type} — Retrieve a config file Reads an application config file and returns its values as flattened dot-notation key/value pairs, plus the raw file content. The `config_type` is validated against the known-config allowlist. **Access** API scope: `servers:properties:read` — Read a server's server.properties entries. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `config_type` (path, required): Config type key (for example `bukkit`) Responses: `200` Config file contents; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or config type not found; `429` Rate limited; `502` Upstream error: Node could not read the config file ### PUT /servers/{server_id}/properties/configs/{config_type} — Update a config file Applies dot-notation updates to an application config file: reads the file, merges the provided keys, and writes it back, preserving everything you did not send. `server.properties` is rejected — use `PUT /properties` instead. Returns the updated config file. **Access** API scope: `servers:properties:write` — Update a server's server.properties entries. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `config_type` (path, required): Config type key (for example `bukkit`) - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Config file updated; `400` Bad request: Empty values or unsupported config type; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or config type not found; `429` Rate limited; `502` Upstream error: Node could not read or write the config file ## Instances ### GET /servers/{server_id}/instances — List instances Lists the server's instance profiles. The default parent profile is created on first use. **Access** API scope: `servers:instances:read` — List a server's instances and clone jobs. Server access: owner, or server permission `instance.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Server instances; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Instance service unavailable ### POST /servers/{server_id}/instances — Create an instance Creates a new instance profile (at most 10 per server). Pick a supported application via `target_config_id` for a guided runtime, or omit it to copy the active profile's runtime. **Access** API scope: `servers:instances:write` — Create, update, activate, and clone server instances. Server access: owner, or server permission `instance.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Instance created; `400` Bad request: Invalid instance data; `401` Authentication: Invalid or missing API key; `402` Payment required: Application not available on the free plan; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Instance service unavailable ### GET /servers/{server_id}/instances/clone-jobs — List clone jobs Lists the server's recent instance clone jobs, newest first. **Access** API scope: `servers:instances:read` — List a server's instances and clone jobs. Server access: owner, or server permission `instance.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Clone jobs; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Instance service unavailable ### GET /servers/{server_id}/instances/clone-jobs/{job_id} — Get a clone job Retrieves one clone job by id, refreshing its progress from the node when still running. **Access** API scope: `servers:instances:read` — List a server's instances and clone jobs. Server access: owner, or server permission `instance.read`. Parameters: - `server_id` (path, required): Falix server id - `job_id` (path, required): Clone job id Responses: `200` Clone job; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or clone job not found; `429` Rate limited; `503` Service unavailable: Instance service unavailable ### DELETE /servers/{server_id}/instances/{instance_id} — Delete an instance Permanently deletes an inactive, non-default instance profile and its instance directory. Requires the explicit-grant `servers:instances:delete` scope, which is never granted by wildcards. **Access** The servers:instances:delete scope is never granted by wildcards and must be granted explicitly. Parameters: - `server_id` (path, required): Falix server id - `instance_id` (path, required): Instance id/key - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Instance deleted; `400` Bad request: Cannot delete the default or active instance; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or instance not found; `409` Conflict: A clone of this instance is in progress; `429` Rate limited; `503` Service unavailable: Instance service unavailable ### PATCH /servers/{server_id}/instances/{instance_id} — Update an instance Updates an instance profile's label, application, or metadata. Changing the application of the active instance requires the server to be offline. **Access** API scope: `servers:instances:write` — Create, update, activate, and clone server instances. Server access: owner, or server permission `instance.update`. Parameters: - `server_id` (path, required): Falix server id - `instance_id` (path, required): Instance id/key - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Instance updated; `400` Bad request: Invalid instance data; `401` Authentication: Invalid or missing API key; `402` Payment required: Application not available on the free plan; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server or instance not found; `409` Conflict: A clone of this instance is in progress, or the server is not offline; `429` Rate limited; `503` Service unavailable: Instance service unavailable ### POST /servers/{server_id}/instances/{instance_id}/activate — Activate an instance Switches the server to another instance profile. The server must be offline; the switch is verified with the node and rolled back on failure. Pass `reinstall=true` to start a reinstall once the switch is verified. **Access** API scope: `servers:instances:write` — Create, update, activate, and clone server instances. Server access: owner, or server permission `instance.activate`. Parameters: - `server_id` (path, required): Falix server id - `instance_id` (path, required): Instance id/key - `reinstall` (query): Start a reinstall after the switch is verified. - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Instance activated; `400` Bad request: Invalid instance id; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server or instance not found; `409` Conflict: Server is not offline, or a clone is in progress; `429` Rate limited; `502` Upstream error: Server node rejected the switch; `503` Service unavailable: Instance service unavailable ### POST /servers/{server_id}/instances/{source_instance_id}/clone — Clone an instance Starts a background copy of one instance directory into a new instance and returns `202 Accepted` with the clone job. Poll `GET /servers/{server_id}/instances/clone-jobs/{job_id}` until the job completes. Retrying with the same `idempotency_key` returns the existing job. **Access** API scope: `servers:instances:write` — Create, update, activate, and clone server instances. Server access: owner, or server permission `instance.clone`. Parameters: - `server_id` (path, required): Falix server id - `source_instance_id` (path, required): Source instance id/key - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Instance clone started; `400` Bad request: Invalid clone request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server or source instance not found; `409` Conflict: Source is running, instance limit reached, or another clone is active; `429` Rate limited; `502` Upstream error: Server node could not start the clone; `503` Service unavailable: Instance service unavailable ## Subusers ### GET /servers/{server_id}/subusers — List subusers Returns every user with delegated access to the server, with their granted permissions. **Access** API scope: `servers:subusers:read` — List users with delegated access to a server and their permissions. Server access: owner, or server permission `user.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Server subusers; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Subuser service unavailable ### POST /servers/{server_id}/subusers — Add a subuser Grants a user access to the server with the given permissions. Identify the target with exactly one of `email`, `username`, or `user_id`. If the user already has access, their permission set is replaced. **Access** API scope: `servers:subusers:write` — grants access on your behalf, so it is never granted by the `servers:*` wildcard and must be granted to the key explicitly. Server access: owner, or server permission `user.update`. You cannot modify your own subuser entry. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Subuser added; `400` Bad request: Invalid identifier or permissions; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or self-modification attempt; `404` Not found: Server or target user not found; `429` Rate limited; `503` Service unavailable: Subuser service unavailable ### PUT /servers/{server_id}/subusers/{user_id} — Update subuser permissions Replaces the permission set of an existing subuser, identified by panel user id. **Access** API scope: `servers:subusers:write` — never granted by the `servers:*` wildcard; grant it explicitly. Server access: owner, or server permission `user.update`. You cannot modify your own subuser entry. Parameters: - `server_id` (path, required): Falix server id - `user_id` (path, required): Panel user id of the subuser - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Subuser permissions updated; `400` Bad request: Invalid permissions; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or self-modification attempt; `404` Not found: Server or subuser not found; `429` Rate limited; `503` Service unavailable: Subuser service unavailable ### DELETE /servers/{server_id}/subusers/{user_id} — Remove a subuser Revokes a user's access to the server. You cannot remove your own access. **Access** API scope: `servers:subusers:write` — never granted by the `servers:*` wildcard; grant it explicitly. Server access: owner, or server permission `user.update`. You cannot remove your own subuser entry. Parameters: - `server_id` (path, required): Falix server id - `user_id` (path, required): Panel user id of the subuser - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Subuser removed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or self-removal attempt; `404` Not found: Server or subuser not found; `429` Rate limited; `503` Service unavailable: Subuser service unavailable ## Activity ### GET /me/activity — List account activity Returns the authenticated account's own activity log — actions not tied to a specific server, newest first. Like the server activity endpoint, IP addresses, user-agent strings, actor emails, and raw internal metadata are intentionally omitted. **Access** API scope: `servers:activity:read`. Returns the API key owner's own account activity (events not tied to a specific server). No server permission applies — the endpoint is account-scoped. Parameters: - `limit` (query): Maximum number of events to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of events to skip. Defaults to `0`. Responses: `200` Account activity; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Activity service unavailable ### GET /servers/{server_id}/activity — List server activity Returns recent activity for a server. The response intentionally omits IP addresses, user-agent strings, actor emails, and raw internal metadata. **Access** API scope: `servers:activity:read` — Read sanitized server activity events. Server access: owner, or server permission `activity.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of events to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of events to skip. Defaults to `0`. Responses: `200` Server activity; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server state does not allow activity reads; `429` Rate limited ## FalixInit ### GET /init/templates — List init templates Returns the account's saved FalixInit manifest templates, newest first. **Access** API scope: `templates:read` — List and read the account's saved FalixInit templates, and dry-run validate manifests.. Parameters: - `limit` (query): Maximum number of templates to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of templates to skip. Defaults to `0`. Responses: `200` Saved templates; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Template service unavailable ### POST /init/templates — Create an init template Saves a reusable FalixInit manifest. The manifest is validated against the paid tier's (looser) caps so it can be applied on any plan; the actual server-create flow re-validates it at the server's real tier. Names are unique per account. **Access** API scope: `templates:write` — Create, update, and delete the account's saved FalixInit templates.. Parameters: - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Template created; `400` Bad request: Invalid name or description; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `409` Conflict: Duplicate name or template limit reached; `422` Validation: Manifest failed validation; `429` Rate limited; `503` Service unavailable: Template service unavailable ### GET /init/templates/{template_id} — Get an init template Returns a single saved template by id. **Access** API scope: `templates:read` — List and read the account's saved FalixInit templates, and dry-run validate manifests.. Parameters: - `template_id` (path, required): Template id Responses: `200` Template; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `404` Not found: Template not found; `429` Rate limited; `503` Service unavailable: Template service unavailable ### DELETE /init/templates/{template_id} — Delete an init template Removes a saved template by id. **Access** API scope: `templates:write` — Create, update, and delete the account's saved FalixInit templates.. Parameters: - `template_id` (path, required): Template id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Template removed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `404` Not found: Template not found; `429` Rate limited; `503` Service unavailable: Template service unavailable ### PATCH /init/templates/{template_id} — Update an init template Updates any subset of a template's name, description, and manifest. A supplied manifest replaces the stored one in full and is re-validated at the paid tier's (looser) caps. **Access** API scope: `templates:write` — Create, update, and delete the account's saved FalixInit templates.. Parameters: - `template_id` (path, required): Template id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Template updated; `400` Bad request: Invalid name or description; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `404` Not found: Template not found; `409` Conflict: Duplicate name; `422` Validation: Manifest failed validation; `429` Rate limited; `503` Service unavailable: Template service unavailable ### POST /init/validate — Validate a FalixInit manifest Dry-runs a manifest without provisioning anything. Supply an inline `init` body, a saved `template_id`, or both (the inline body is merged onto the template). A `422` with field-level errors is returned when the manifest is invalid; each error's field is prefixed `init.` (template resolution errors stay on `template_id`). FalixInit declares a server's first boot in one YAML document instead of a series of API calls: software and content, config files, environment, remote assets, first-boot commands, schedules, webhooks, and subuser access. Pass it as `init` on `POST /servers`, save reusable account templates under `/init/templates`, and lint any manifest here (`POST /init/validate`) before using it. ### A complete manifest ```yaml #falix-init version: 1 application: slug: minecraft-java loader: paper version: "1.21" plugins: - source: modrinth id: P7dR8mSH - source: url url: https://example.com/plugins/backup.jar sha512: 3c9909afec… size: 1048576 env: MOTD: Provisioned by FalixInit startup: command: java -Xmx{{SERVER_MEMORY}}M -jar server.jar files: - path: server.properties content: | view-distance=8 motd=Hello - path: config/secret.bin content_base64: aGVsbG8= mode: "0600" assets: - url: https://example.com/world.tar.gz size: 52428800 sha256: 2cf24dba… extract: true extract_path: world run: commands: - say Server provisioned timeout: 300 final_state: running schedules: - name: nightly restart cron: "0 4 * * *" only_when_online: true tasks: - action: command payload: say restarting in 60s - action: power payload: restart time_offset: 60 hooks: - url: https://hooks.example.com/falix events: [server.installed, server.crashed] access: - email: friend@example.com permissions: [control.console, control.start] ``` ### Rules that matter - The first line must be exactly `#falix-init`, `version` must be `1`, and the whole document is capped at 48 KB. Unknown keys anywhere are rejected. Validation collects **every** problem in one pass and reports each with its exact field path (`assets[0].size`), so one lint round trip is enough. - Every section is optional — the smallest valid manifest is the header plus `version: 1`. - `application` picks what to deploy: `slug` **or** `id` (from `GET /applications`), optional `version`, `java` major, and `loader` (`paper`, `purpur`, `spigot`, `vanilla`, `fabric`, `forge`, `neoforge`, `bedrock`). Plugins and mods come from Modrinth (`source: modrinth` with a project `id`, optionally pinned to a `version`) or a direct download (`source: url`, with declared `size` and an optional `sha512`/`sha1`). - `files` writes inline content: exactly one of `content` (UTF-8) or `content_base64`, optional octal `mode` like `"0644"`, and `append: true` to append instead of overwrite. - `assets` downloads remote files into the server root; `size` is required, checksums (`sha256`/`sha512`/`sha1`) are strongly recommended, and `extract: true` unpacks archives (into `extract_path` when given). - `run` is either a bare YAML list of console commands or a struct with `commands`, `timeout` (default 120s, max 900), and `final_state` (`running` or `stopped`). - `schedules` fire on a 5-field `cron` **or** an `event` trigger (the same event set as the Webhooks guide), with up to 5 `tasks` each — `action` is `command`, `power`, or `backup`, with optional `time_offset` seconds between tasks. - `hooks` registers signed webhooks with the same delivery contract and event set as the Webhooks guide; supply a 16–128 character `secret` or one is generated. - `access` grants subuser permissions by `email`, `username`, or `user_id`. ### Caps by plan | Limit | Free | Paid | | --- | --- | --- | | Plugins + mods | 25 | 100 | | Single download | 200 MiB | 2 GiB | | `env` keys | 32 | 128 | | `files` entries | 15 | 50 | | Single file / all files | 64 KiB / 256 KiB | 128 KiB / 1 MiB | | `assets` entries / total | 3 / 500 MiB | 10 / 5 GiB | | `run` commands | 10 | 30 | | `schedules` | 2 | 20 | | `hooks` | 1 | 5 | | `access` grants | 1 | 10 | Templates are validated against the looser paid caps at save time so a stored manifest is usable on any plan; `POST /servers` re-validates at the server's real tier. Lint against a specific tier with the `tier` field on `POST /init/validate`. ### Execution and progress Provisioning runs the phases `content` → `files` → `env` → `registrations` (schedules, access, hooks) → `run` → `finalize`. Follow along with `GET /servers/{server_id}/init`: `state` is `queued`, `running`, `completed`, `partial`, `failed`, or `timed_out`, with per-phase results, `progress`, and accumulated `warnings`. Hard phases (`content`, `files`, `env`) fail the job with a precise error; soft phases (`registrations`, `run`) record warnings and continue — a job that finished with warnings ends as `partial`, never silently. ### Templates and overlays Save reusable manifests with `POST /init/templates`, then pass `template_id` to `POST /servers` or `POST /init/validate` — optionally together with an inline `init` overlay whose top-level keys replace the template's. This keeps one golden template per fleet with per-server tweaks inline. ### Current limitations - Modrinth entries may be skipped with a warning in some configurations — prefer `source: url` with checksums for content that must not be skipped. - A manifest mixing direct plugin/mod downloads with extractable archive `assets` applies the direct files and skips the archives with a warning; split them across `files`/`assets` accordingly. **Access** Account-level dry-run; provisions nothing. Parameters: - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Manifest is valid; `400` Bad request: Neither init nor template_id supplied, or invalid tier; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `422` Validation: Manifest failed validation; `429` Rate limited; `503` Service unavailable: Template service unavailable ### GET /servers/{server_id}/init — Get server init progress Returns the latest FalixInit provisioning job for a server, including live phase progress. A `404` is returned when the server never ran FalixInit. **Access** API scope: `servers:read` — List servers, read server details, and read live status.. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Latest init job; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found or no init job; `429` Rate limited; `503` Service unavailable: Init service unavailable ## WebSocket ### POST /servers/{server_id}/console/token — Create a console session Issues a short-lived WebSocket token for the server's node. Connect to `socket` and authenticate with `token` to stream live console output and send commands — the API never proxies the stream. Tokens expire after about 10 minutes; request a new session to reconnect. Live console output, resource stats, and power state are streamed over a WebSocket served directly by the server's node — the API mints the credentials but never proxies the stream, and your API key is never sent to the socket. ### Connecting Call `POST /servers/{server_id}/console/token` (scope `servers:console`). The response contains the `socket` URL, a short-lived `token` (about 10 minutes), and the `permissions` embedded in that token. Open the socket URL, then authenticate in-band by sending the token as your first message — nothing else is accepted before authentication: ```json {"event": "auth", "args": [""]} ``` On success the node replies with `auth success`, the current `status`, and a `stats` snapshot. Every frame in both directions is a JSON text envelope of the form `{"event": "...", "args": ["..."]}` — `args` is always an array of strings and may be omitted when empty. The envelope is compatible with Pterodactyl's console socket, plus a scrollback extension (`send history`). ### Messages you can send | Event | `args` | Token permission | |---|---|---| | `auth` | `[token]` | — | | `send logs` | — | `control.console` | | `send history` | `[cursor?, page_len?]` | `control.console` | | `send stats` | — | — | | `send command` | `[command]` | `control.command` | | `set state` | `[action]` | `control.start` / `control.stop` / `control.restart` | `set state` takes one action argument: `"start"`, `"stop"`, `"restart"`, or `"kill"`. `send logs` replays the most recent console output (up to 500 lines). `send history` pages older scrollback: pass the `cursor` from the previous reply (omit it for the newest page) and an optional page length (1–1000, default 200); the reply is a `history output` event whose single argument is JSON: `{"data": [lines], "cursor": , "has_more": }`. ### Events you receive | Event | `args` | Meaning | |---|---|---| | `auth success` | — | Authentication accepted | | `status` | `[state]` | Power state: `offline`, `starting`, `running`, or `stopping` | | `console output` | `[line]` | One console line (ANSI colors preserved; node-originated lines are prefixed `[Falcon]:`) | | `stats` | `[json]` | Resource snapshot (see below); also pushed every 5s while the server is offline | | `history output` | `[json]` | Reply to `send history` | | `install started` / `install output` / `install completed` | — / `[line]` / `[bool]` | Install progress | | `transfer logs` / `transfer status` | `[line]` / `[json]` | Server-transfer progress; `transfer status` JSON carries `phase`, `title`, `message`, `progress`, `terminal` | | `crash restart pending` | `[bool]` | Crash-detection auto-restart state (`"true"` or `"false"`) | | `git:deployment.started` / `git:deployment.progress` / `git:deployment.completed` / `git:deployment.failed` | — / `[line]` / — / `[message]` | Git deployment progress | | `daemon message` / `daemon error` | `[line]` | Informational or error messages from the node | | `token expiring` / `token expired` | — | Renew your token (see below) | | `jwt error` | `[reason]` | Authentication problem; the socket stays open | | `deleted` | — | The server was deleted; disconnect | The `stats` argument is JSON: `{"memory_bytes", "memory_limit_bytes", "cpu_absolute", "network": {"rx_bytes", "tx_bytes"}, "uptime", "state", "disk_bytes"}`. Delivery of install, transfer, and node-error events depends on the permissions embedded in your token — check the `permissions` field of the session response. ### Renewing the token About a minute before expiry the node sends `token expiring`; at expiry it sends `token expired` and stops honoring privileged messages, but keeps the socket open. Mint a new session with `POST /servers/{server_id}/console/token` and send a fresh `auth` message on the same connection — no reconnect needed. ### Good to know - Console scrollback is WebSocket-only (`send logs` / `send history`). Over plain HTTP you can read a server's on-disk log files instead: `GET /servers/{server_id}/files/content?path=/logs/latest.log`. - Authentication failures never close the socket: you get a `jwt error` event and can retry with a fresh token. - Browser connections are checked against the allowed origins; non-browser clients can simply omit the `Origin` header. A disallowed origin is rejected with HTTP 403 at the upgrade. - Inbound text frames are capped at 64 KiB; binary frames are ignored. Console lines are capped at 4096 bytes. - If your client reads too slowly, skipped output is replaced with a `console output` line reading `N console lines skipped (slow connection)` rather than silently dropping data. **Access** API scope: `servers:console` — Issue short-lived WebSocket tokens for live console access. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Server ID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Console session issued; `401` Authentication: Invalid API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server or node not found; `409` Conflict: Server is in storage mode; `429` Rate limit exceeded ## Files ### GET /servers/{server_id}/files — List a directory Returns the files and directories at `directory`. Results are paginated with `limit`/`offset`; `pagination.total` reports the full number of entries the node listed for the directory. Ordering matches the node's directory listing. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `directory` (query): Directory to list. Defaults to the server root (`/`). - `limit` (query): Maximum number of entries to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of entries to skip. Defaults to `0`. Responses: `200` Directory listing; `400` Bad request: Invalid path or query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/files/content — Read file content Returns the UTF-8 text content of a file. Binary files are rejected — use the signed download URL endpoint for those. Enforces the `file.read-content` permission, matching the dashboard's text read. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read-content`. Parameters: - `server_id` (path, required): Falix server id - `path` (query, required): Absolute path of the file to read. Responses: `200` File content; `400` Bad request: Invalid path or binary file; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### PUT /servers/{server_id}/files/content — Write file content Writes inline UTF-8 content to a file, creating it if needed. Inline request bodies are limited to 64 KB; for larger files, request a signed upload URL with `POST /servers/{server_id}/files/upload`. Blocked on suspended servers. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` File written; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Request body too large; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/copy — Copy a file Copies a file in place; the node creates an adjacent copy. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` File copied; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/delete — Delete files Permanently deletes one or more files. Unlike the dashboard, which moves files to a per-server trash, the public API deletes files immediately; there is no trash to restore from. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.delete`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files deleted; `400` Bad request: Invalid path or no files specified; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/folder — Create a directory Creates a new folder `name` inside the parent directory `path`. Blocked on suspended servers. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Folder created; `400` Bad request: Invalid path or name; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/move — Move a file Moves a file from `from` to `to`. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` File moved; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/rename — Rename a file Renames or moves a file from `from` to `to`. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` File renamed; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/sftp — Retrieve SFTP connection details Returns the hostname, port, and username for connecting to the server over SFTP. Authenticate with your account password or an SSH key added from the dashboard. **Access** API scope: `servers:sftp:read` — Read a server's SFTP hostname, port, and username. No password is ever returned. Server access: owner, or server permission `file.sftp`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` SFTP connection details; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or account username; `404` Not found: Server or node not found; `429` Rate limited; `503` Service unavailable: SFTP service unavailable ## File Tools ### POST /servers/{server_id}/files/chmod — Change file permissions Sets Unix permission bits on one or more files using octal mode strings (`644`, `0755`). Modes are validated before the request reaches the node. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Permissions changed; `400` Bad request: Invalid path, octal mode, or no files; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/compress — Compress files Compresses the given paths into a `tar.gz` archive in `directory`. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Archive created; `400` Bad request: Invalid path or no files specified; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/decompress — Decompress an archive Extracts an archive into `directory`. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.delete`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Archive extracted; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/files/disk-usage — Directory disk usage Returns a size breakdown of the entries directly under `directory`, sorted largest first, each with its share of the directory total. Large directories may take up to a minute to compute. The dashboard's separate per-path `sizes` lookup is folded in here: it is a UI lazy-load helper for filling in folder sizes on demand, and this endpoint already returns per-entry sizes for a directory. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `directory` (query): Directory to analyze. Defaults to the server root (`/`). - `limit` (query): Maximum number of entries to return (clamped to `1..=100`). - `recursive` (query): Whether to recurse into subdirectories. Responses: `200` Disk usage breakdown; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/files/history — List file change history Returns the recorded change history for a file (writes via the editor, SFTP, uploads, or the API), newest first, with unified diffs where available. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read-content`. Parameters: - `server_id` (path, required): Falix server id - `path` (query, required): Absolute path of the file to list history for. - `limit` (query): Maximum entries to return (clamped to `1..=50`). - `offset` (query): Number of entries to skip. Responses: `200` File change history; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: History service unavailable ### GET /servers/{server_id}/files/search — Search files by name Searches for files whose name matches `query` under `directory`. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `query` (query, required): Search query matched against file names. - `directory` (query): Directory to search from. Defaults to the server root (`/`). Responses: `200` Search results; `400` Bad request: Empty query or invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/files/search/content — Search inside file contents Grep-like search that returns matching lines and their context from inside files under `directory`. The node scans at most 2 MB per file. Distinct from `GET /files/search`, which matches on file names only. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `query` (query, required): Text to search for inside files. Must be at least 2 characters. - `directory` (query): Directory to search from. Defaults to the server root (`/`). - `case_sensitive` (query): Whether the match is case-sensitive. - `context_lines` (query): Lines of surrounding context per match (clamped to `0..=10`). - `limit` (query): Maximum matches to return (clamped to `1..=500`). - `extensions` (query): Comma-separated file extensions to restrict the search to (e.g. `yml,properties`). Responses: `200` Content search results; `400` Bad request: Query too short or invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ## Archives & NBT ### GET /servers/{server_id}/files/archive — List archive contents Inspects an archive (`.zip`, `.tar.gz`, …) without extracting it, returning its entries with sizes. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `path` (query, required): Absolute path of the archive to inspect. - `directory` (query): Root directory the archive path is resolved against. Defaults to `/`. Responses: `200` Archive contents; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/archive/extract — Extract from an archive Extracts an archive into `directory`. When `files` is empty the whole archive is extracted; otherwise only the listed entries are. Large archives may take up to 10 minutes. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Archive extracted; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/files/nbt — Read an NBT file Downloads and parses an arbitrary `.dat`/`.nbt`/`.schematic`/`.schem` file by path into a structured tree. This is distinct from the world-level `level.dat` editor under `/worlds/nbt`: it reads any NBT file, not just a world's `level.dat`. Files larger than 5 MB are rejected. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read-content`. Parameters: - `server_id` (path, required): Falix server id - `path` (query, required): Absolute path of the NBT file to read. Responses: `200` Parsed NBT tree; `400` Bad request: Invalid path, extension, or file too large; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### PUT /servers/{server_id}/files/nbt — Write an NBT file Writes a structured NBT tree back to a .dat/.nbt/.schematic/.schem file. Accepts bodies up to 4 MB with idempotent retries. **Access** Accepts request bodies up to 4 MB with idempotent retries. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` NBT file written; `400` Bad request: Invalid path, extension, format, or data; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Body exceeded 4 MB; `429` Rate limited; `502` Upstream error: Node could not complete the request ## File Transfers ### POST /servers/{server_id}/files/copy-to — Copy or move files to another directory Copies (`mode=copy`) or moves (`mode=cut`) files to another directory on the same server, resolving name collisions automatically. Maximum 100 items. **Access** Cut mode (`mode=cut`) also requires the `file.update` permission. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files copied or moved; `400` Bad request: Invalid path, mode, or too many items; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/download — Create a download URL Returns a short-lived signed URL for downloading a file directly from the node. `GET` the returned `url` within the expiry window. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Signed download URL; `400` Bad request: Invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or node not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Node service unavailable ### POST /servers/{server_id}/files/pull — Pull a file from a URL Asks the node to download a file from a remote `http(s)` URL into the server. The URL is vetted against private, loopback, and cloud-metadata hosts before the node is asked to fetch it. Poll `GET /files/pull/status` for progress. Blocked on suspended servers. **Access** Blocked on suspended servers. The source URL is vetted against private and metadata hosts before the node fetches it. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Pull accepted and started; `400` Bad request: Invalid URL, path, or filename; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### GET /servers/{server_id}/files/pull/status — Get URL pull status Returns the in-progress URL downloads for the server, each with its completion fraction. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Active downloads; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/transfer — Transfer files to another server Copies files from this server to another server you own by generating a signed download on the source and pulling it onto the target. Maximum 50 files. Rate limited. The API key must hold `servers:files:read` (plus `file.read`) on the source server and `servers:files:write` (plus `file.create`) on the target server; both servers are authorized independently. **Access** Also requires the `servers:files:write` scope and `file.create` permission on the target server; both servers are authorized independently. Parameters: - `server_id` (path, required): Source Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files transferred; `400` Bad request: Invalid request or too many files; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission on either server; `404` Not found: Source or target server not found; `409` Conflict: A server is unavailable or in storage mode; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/upload — Create an upload URL Returns a short-lived signed URL for uploading a file directly to the node. Send the file to the returned `url` with a `POST` multipart form and a `&directory=` query parameter. Blocked on suspended servers and storage-mode nodes. Use this for files larger than the 64 KB inline write limit. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Signed upload URL; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server or node not found; `409` Conflict: Server unavailable or in storage mode; `429` Rate limited; `503` Service unavailable: Node service unavailable ## File Trash ### GET /servers/{server_id}/files/trash — List trashed files Returns the files currently in the server's trash. Unlike the public delete endpoint (which removes files immediately), the dashboard moves deletes to this trash, from which they can be restored or permanently removed. Results are paginated with `limit`/`offset`; `pagination.total` reports the full number of trashed entries. **Access** API scope: `servers:files:read` — List directories, read file content, search files, and generate download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of entries to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of entries to skip. Defaults to `0`. Responses: `200` Trash contents; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/trash/delete — Permanently delete trashed files Removes the given trash entries. This cannot be undone. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.delete`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Trash entries deleted; `400` Bad request: No trash entries specified; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/trash/empty — Empty the trash Removes every entry in the server's trash. This cannot be undone. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.delete`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Trash emptied; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ### POST /servers/{server_id}/files/trash/restore — Restore trashed files Moves the given trash entries back to their original paths. On a name collision the node restores under a suffixed name. **Access** API scope: `servers:files:write` — Write, create, rename, copy, move, delete, compress, and upload files. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files restored; `400` Bad request: No trash entries specified; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not complete the request ## Importer ### POST /servers/{server_id}/importer — Import server files Starts a server import from a remote SFTP/FTP server. **Destructive**: the running server is killed, existing files are optionally deleted, the server application is swapped to the importer, and a rebuild is queued. The server restarts with the imported files. The remote host is resolved and vetted (private and internal addresses are rejected), and the credentials are never echoed back. Limited to 5 imports per 5 minutes per key. There is no import job to poll: the import runs as the server itself after the rebuild. Follow progress over the server's console WebSocket, or watch `GET /servers/{server_id}/status` for the server to come back online. **Access** The servers:importer:write scope is never granted by wildcards and must be granted explicitly. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Import started; `400` Bad request: Invalid import parameters or blocked host; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found or importer application not installed; `429` Rate limited; `502` Upstream error: Server node unreachable; `503` Service unavailable: Import service unavailable ## Worlds ### GET /servers/{server_id}/worlds — List worlds Scans the server for world folders and returns each with its edition, dimension type, and whether it is the primary world. **Access** API scope: `servers:worlds:read` — List a server's worlds, search marketplace maps, and generate world download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Detected worlds; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not list worlds ### POST /servers/{server_id}/worlds/download — Create a world download URL Returns a short-lived signed URL for downloading the world folder as a compressed archive directly from the node. The node builds the archive on demand — `GET` the returned `url` within the expiry window to start the download. **Access** API scope: `servers:worlds:read` — read a server's worlds. Server access: owner, or server permission `file.read`. Returns a short-lived signed archive URL; the world contents are downloadable by anyone holding the URL until it expires. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Signed download URL; `400` Bad request: Invalid world name or path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or node not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Node service unavailable ### GET /servers/{server_id}/worlds/maps — Search maps Searches the CurseForge marketplace for Java or Bedrock maps. With no `q`, returns the most-downloaded maps. Returns nine results per page. **Access** API scope: `servers:worlds:read` — List a server's worlds, search marketplace maps, and generate world download URLs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `q` (query): Search text; omit for popular maps - `page` (query): Page number (1-indexed) - `bedrock` (query): Search Bedrock maps instead of Java Responses: `200` Map search results; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### POST /servers/{server_id}/worlds/maps/install — Install a map Installs a CurseForge map: the node downloads the map archive, extracts it, and cleans up the archive before responding. Uses the latest file unless `file_id` is given. **Access** API scope: `servers:worlds:write` — Set the primary world and install maps and Bedrock .mcworld files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Map installed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, project, or file not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not install the map; `503` Service unavailable: Marketplace service unavailable ### POST /servers/{server_id}/worlds/mcworld — Install a `.mcworld` Installs a Bedrock `.mcworld` file: the node downloads (unless already uploaded), extracts, and validates it, moves it into `/worlds/`, and optionally sets it as the primary world — all before responding. **Access** API scope: `servers:worlds:write` — Set the primary world and install maps and Bedrock .mcworld files. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` World installed; `400` Bad request: Invalid URL, filename, or world contents; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not install the world ### GET /servers/{server_id}/worlds/nbt — Read world NBT Downloads and parses a world's `level.dat` (Java gzip big-endian or Bedrock little-endian) or Hytale `config.json`, returning the structured game settings. The edition is auto-detected from the server application unless `nbt_type` is given. **Access** API scope: `servers:worlds:read` — List a server's worlds, search marketplace maps, and generate world download URLs. Server access: owner, or server permission `file.read-content`. Parameters: - `server_id` (path, required): Falix server id - `world` (query, required): World directory name - `nbt_type` (query): Edition hint: java, bedrock, or hytale - `path` (query): Optional full world directory path Responses: `200` Parsed world NBT; `400` Bad request: Invalid world name or parse error; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read level.dat ### PUT /servers/{server_id}/worlds/nbt — Write world NBT Applies NBT path updates to a world's level.dat (or Hytale config.json). Accepts bodies up to 4 MB with idempotent retries. **Access** API scope: `servers:worlds:write`. Server access: owner, or server permission `file.update`. Rewrites `level.dat`; accepts bodies up to 4 MB with idempotent retries. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` World NBT updated; `400` Bad request: Invalid world name, empty updates, or invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Body exceeded 4 MB; `429` Rate limited; `502` Upstream error: Node could not read or write level.dat ### PUT /servers/{server_id}/worlds/primary — Set the primary world Updates `level-name` in `server.properties` so the server loads the given world on startup. A server restart is required for the change to take effect. **Access** API scope: `servers:worlds:write` — Set the primary world and install maps and Bedrock .mcworld files. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Primary world updated; `400` Bad request: Invalid world name; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read or write server.properties ## Players ### GET /servers/{server_id}/players — List players Enumerates known players (data files merged with `ops.json`, `banned-players.json`, and usercache), marks each online/offline from a live game-server query, and supports substring search and pagination. **Access** API scope: `servers:players:read` — List players, read player detail, query online players, read max-players, and preview UUID migrations. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return (default 25, max 100) - `offset` (query): Number of records to skip (default 0) - `search` (query): Substring filter on name or UUID Responses: `200` Players; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not list players ### GET /servers/{server_id}/players/max — Get max players Reads `max-players` from `server.properties`. **Access** API scope: `servers:players:read` — List players, read player detail, query online players, read max-players, and preview UUID migrations. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Max-players setting; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read server.properties ### PUT /servers/{server_id}/players/max — Set max players Updates `max-players` in `server.properties` (0–1000). A restart is required to apply. **Access** API scope: `servers:players:write` — Send player commands, edit player NBT, set max-players, delete player files, and apply UUID migrations. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Max players updated; `400` Bad request: Value out of range (0–1000); `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read or write server.properties ### GET /servers/{server_id}/players/online — Get online players Queries the live game server (Minecraft SLP or Hytale A2S) for online players without reading player data files. Returns `0` with `query_succeeded: false` when the server is unreachable. **Access** API scope: `servers:players:read` — List players, read player detail, query online players, read max-players, and preview UUID migrations. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Online player status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited ### GET /servers/{server_id}/players/resolve — Resolve a player name Resolves a Minecraft Java username to its UUID. By default this looks up the real Mojang (online-mode) UUID; pass `online_mode=false` to compute the deterministic offline/cracked UUID locally without contacting Mojang. Useful for building `whitelist.json` entries. **Access** API scope: `servers:players:read`. Server access: owner, or server permission `file.update`. Runs an external Mojang lookup for online-mode names and is rate limited. Parameters: - `server_id` (path, required): Falix server id - `name` (query, required): Minecraft Java username to resolve - `online_mode` (query): Resolve the Mojang UUID (default) or compute the offline UUID when false Responses: `200` Resolved profile; `400` Bad request: Invalid username; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found or Minecraft profile not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Minecraft profile lookup unavailable ### GET /servers/{server_id}/players/{uuid} — Get a player Returns full player detail: NBT-parsed health, food, XP, position, dimension, gamemode, inventory, ender chest, equipment, effects, and attributes, plus op/whitelist/ban status and live online status. Pass `section` to return only `stats`, `advancements`, or `recipes`. **Access** API scope: `servers:players:read` — List players, read player detail, query online players, read max-players, and preview UUID migrations. Server access: owner, or server permission `file.read-content`. Parameters: - `server_id` (path, required): Falix server id - `uuid` (path, required): Player UUID - `section` (query): Return only this section: stats, advancements, recipes Responses: `200` Player detail; `400` Bad request: Invalid UUID; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or player not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read player data ### POST /servers/{server_id}/players/{uuid}/command — Send a player command Builds and dispatches a Minecraft (or Hytale) command targeting a specific player via the server console: admin (`op`/`ban`/`kick`), gameplay (`heal`/`tp`/`gamemode`), and more. **Access** API scope: `servers:players:write` — Send player commands, edit player NBT, set max-players, delete player files, and apply UUID migrations. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id - `uuid` (path, required): Player UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Command sent; `400` Bad request: Unknown command or invalid arguments; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not run the command ## Player Data ### POST /servers/{server_id}/players/migrate/apply — Apply a UUID migration Executes the plan: renames every player file, rewrites JSON registries, resets plugin caches, and flips `online-mode`. The server **must be stopped**; a completed pre-migration backup is strongly recommended. Destructive: requires the `servers:players:write` scope. **Access** API scope: `servers:players:write`. Server access: owner, or server permissions `file.read` and `file.update`. Destructive: renames every player file and rewrites registries. The server must be stopped; supply a completed `backup_id` so a rollback point exists. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Migration applied; `400` Bad request: Invalid request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server not stopped, server unavailable, or backup incomplete; `429` Rate limited; `502` Upstream error: Node could not apply the migration ### POST /servers/{server_id}/players/migrate/preview — Preview a UUID migration Builds the online⇄offline UUID migration plan without modifying any files: which players will be renamed, which cannot be, collisions, and the registries and plugins affected. **Access** API scope: `servers:players:read` — List players, read player detail, query online players, read max-players, and preview UUID migrations. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Migration plan; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read player data ### DELETE /servers/{server_id}/players/{uuid}/files — Delete player files Deletes the player's `playerdata` (`.dat`), `stats` (`.json`), or `advancements` (`.json`) file. Destructive and not recoverable. **Access** API scope: `servers:players:write`. Server access: owner, or server permission `file.delete`. Destructive: permanently deletes the player's data file. Parameters: - `server_id` (path, required): Falix server id - `uuid` (path, required): Player UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Player file deleted; `400` Bad request: Invalid UUID or file type; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not delete player data ### GET /servers/{server_id}/players/{uuid}/inventory — Get a player's inventory Returns the player's main inventory, ender chest, and equipped items parsed from their NBT data. This is the inventory subset of the full player detail endpoint. **Access** API scope: `servers:players:read` — List players, read player detail, query online players, read max-players, and preview UUID migrations. Server access: owner, or server permission `file.read-content`. Parameters: - `server_id` (path, required): Falix server id - `uuid` (path, required): Player UUID Responses: `200` Player inventory; `400` Bad request: Invalid UUID; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or player not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not read player data ### PATCH /servers/{server_id}/players/{uuid}/inventory — Edit a player's inventory Edits a player's inventory via console commands (clear, give, move, delete-item, clear-enderchest). Accepts bodies up to 4 MB with idempotent retries. **Access** API scope: `servers:players:write`. Server access: owner, or server permission `control.console` — inventory edits run as console commands. Accepts bodies up to 4 MB with idempotent retries. Parameters: - `server_id` (path, required): Falix server id - `uuid` (path, required): Player UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Inventory command executed; `400` Bad request: Unknown command or invalid arguments; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Body exceeded 4 MB; `429` Rate limited; `502` Upstream error: Node could not run the command ### PATCH /servers/{server_id}/players/{uuid}/nbt — Update player NBT Reads the player's `.dat`, applies each field update with optional type coercion, and writes it back. Up to 50 updates per request. **Access** API scope: `servers:players:write` — Send player commands, edit player NBT, set max-players, delete player files, and apply UUID migrations. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `uuid` (path, required): Player UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` NBT fields updated; `400` Bad request: Invalid UUID, empty updates, or too many updates; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or player data not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not update player data ## Addons ### GET /servers/{server_id}/addons — List installed addons Enumerates the server's installed plugins, mods, and datapacks. By default each addon is matched against Modrinth by file hash and enriched with project metadata and update availability; pass `detailed=false` for a fast bare listing. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `detailed` (query): Enrich with Modrinth metadata (default true) Responses: `200` Installed addons; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not list addons ### POST /servers/{server_id}/addons/configure — Auto-configure a plugin Runs the plugin auto-configuration flow: allocates or reuses a port and writes a templated config for a supported plugin (`geysermc`, `floodgate`, `simple-voice-chat`, `votifier`, or a Geyser platform). Downloads the plugin to the server when required. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Plugin configured; `400` Bad request: Missing or unsupported slug, or no available port; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not write the config; `503` Service unavailable: Marketplace service unavailable ### POST /servers/{server_id}/addons/dependencies — Resolve dependencies Looks up marketplace metadata for a list of project ids. Use this to preview a project's dependencies before installing. Unresolvable ids are dropped. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Resolved dependency projects; `400` Bad request: Empty, too many, or invalid project ids; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### POST /servers/{server_id}/addons/install — Install an addon Resolves the latest marketplace version compatible with the server's loader and Minecraft version, recursively resolves required dependencies, skips any file already present, and pulls everything to the server in one call. Supports `mod`, `plugin`, and `datapack` installs from Modrinth, CurseForge, or Spiget, plus Bedrock addon installs from CurseForge. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Install result (may report no compatible version); `400` Bad request: Invalid source, project id, or missing loader/version; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or project not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not download the addon; `503` Service unavailable: Marketplace service unavailable ### POST /servers/{server_id}/addons/modpack — Install a modpack (async) Starts a modpack install as a background job and returns `202 Accepted` with a job object immediately. Poll `GET /servers/{server_id}/addons/modpack/jobs/{job_id}` for progress. Never blocks on the install. **Access** API scope: `servers:addons:write` — manage a server's addons. Server access: owner, or server permission `file.update`; `clean` mode also requires `file.delete`. Starts a background install job and returns 202. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Install job accepted; `400` Bad request: Invalid request shape; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable, suspended, or in storage mode; `429` Rate limited; `502` Upstream error: Node communication error; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/modpack/jobs/{job_id} — Get a modpack job Returns the current state, progress, and any warnings or errors of a modpack install job started on this server. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `job_id` (path, required): Modpack install job id Responses: `200` Modpack job status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or job not found; `429` Rate limited; `503` Service unavailable: Modpack job service unavailable ### POST /servers/{server_id}/addons/set-version — Switch server software/version Records a new software and version for the server from the version catalogue (see `GET /servers/{server_id}/software/versions`). For most software this only updates metadata; switching to Bedrock or PocketMine reinstalls the server (rewrites the runtime egg, Docker image, and startup variables) and writes `eula.txt` where required. **Access** API scope: `servers:addons:write` — manage a server's addons. Server access: owner, or server permission `file.create`. Switches the server's software/version; Bedrock and PocketMine targets reinstall the server (rewriting the runtime egg, Docker image, and startup variables). Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Software/version switched; `400` Bad request: Invalid software or version; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not reinstall the server; `503` Service unavailable: Version data unavailable ### POST /servers/{server_id}/addons/toggle — Toggle an addon Enables or disables an installed addon by renaming its file to add or remove the `.disabled` suffix. A restart is required for the change to take effect. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Addon toggled; `400` Bad request: Invalid filename, extension, or addon type; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not rename the addon ### GET /servers/{server_id}/software/versions — List software versions Returns the version catalogue used when installing or switching server software. With no `software`, returns the full catalogue; with `software`, returns that software's versions; with `software` and `version`, returns the available builds for that version. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `software` (query): Software key (for example paperspigot, fabric) - `version` (query): Version to list builds for (requires software) Responses: `200` Software version catalogue; `400` Bad request: Invalid software type; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Version data unavailable ## Marketplace ### GET /servers/{server_id}/addons/content/changelog — Get a content changelog Fetches the changelog text for one published version of a marketplace project. Supported for `modrinth` and `curseforge`; other sources embed their changelog in the version data and return `400`. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `id` (query, required): Project id on the source platform - `file_id` (query, required): Version/file id whose changelog to fetch - `source` (query, required): Source platform (modrinth | curseforge) Responses: `200` Content changelog; `400` Bad request: Missing parameters or source without separate changelogs; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/content/changelog/timeline — Get a changelog timeline Fetches the changelog text for a project's recent versions in one call (newest first, up to 25). Supported for `modrinth` and `curseforge`. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `id` (query, required): Project id on the source platform - `source` (query, required): Source platform (modrinth | curseforge) - `limit` (query): Max versions to include (default 15, max 25) Responses: `200` Changelog timeline; `400` Bad request: Missing parameters or unsupported source; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/content/details — Get content details Fetches full marketplace project details for one project, normalized to a Modrinth-shaped object regardless of the source platform. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `id` (query, required): Project id on the source platform - `source` (query, required): Source platform - `content_type` (query): Content type hint Responses: `200` Content details; `400` Bad request: Missing parameters or unknown source; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/content/related — List related content Returns marketplace projects related to the given one, matched by shared categories and project type. Only the `modrinth` source is supported; other sources return `400`. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `id` (query, required): Project id on the source platform - `source` (query, required): Source platform (modrinth only) - `page` (query): Page number (1-indexed) Responses: `200` Related projects; `400` Bad request: Missing parameters or unsupported source; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/content/versions — List content versions Fetches the list of published versions for one marketplace project. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `id` (query, required): Project id on the source platform - `source` (query, required): Source platform - `content_type` (query): Content type hint Responses: `200` Content versions; `400` Bad request: Missing parameters or unknown source; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/search — Search the marketplace Consolidated marketplace search for the five primary content types. Set `type` to `plugins`, `mods`, `modpacks`, `datapacks`, or `resourcepacks`. Each type defaults to the best provider for it (plugins: Spiget; mods, datapacks, resourcepacks: Modrinth; modpacks: CurseForge) unless `provider` is given. Returns nine results per page. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `type` (query, required): plugins | mods | modpacks | datapacks | resourcepacks - `provider` (query): Marketplace provider override - `query` (query): Search text - `page` (query): Page number (1-indexed) - `sort` (query): downloads | relevance | follows | newest | updated - `game_version` (query): Filter by Minecraft version - `loader` (query): Filter by mod loader (mods only) Responses: `200` Search results; `400` Bad request: Unknown content type or provider; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ## Custom Packs ### GET /servers/{server_id}/addons/custom-packs — List custom packs Lists the API key owner's custom packs, with the installed flag and pending change count relative to this server. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Custom packs; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/addons/custom-packs — Create a custom pack Creates a new empty custom pack owned by the API key holder. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Pack created; `400` Bad request: Invalid name, loader, version, or icon; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Pack limit reached; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/addons/custom-packs/fork — Fork a marketplace modpack Imports a marketplace modpack (Modrinth or CurseForge) into a new editable custom pack owned by the API key holder. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Pack forked; `400` Bad request: Invalid source or modpack reference; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or modpack not found; `409` Conflict: Pack limit reached; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### GET /servers/{server_id}/addons/custom-packs/{pack_id} — Get a custom pack Returns a custom pack's metadata and full item list. The pack must be owned by the API key holder. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id Responses: `200` Custom pack; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server or pack not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### DELETE /servers/{server_id}/addons/custom-packs/{pack_id} — Delete a custom pack Permanently deletes a custom pack and its items. The pack must be owned by the API key holder. Does not touch mods already installed on any server. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Pack deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server or pack not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### PATCH /servers/{server_id}/addons/custom-packs/{pack_id} — Update a custom pack Updates a pack's metadata. Only supplied fields change. The pack must be owned by the API key holder. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Pack updated; `400` Bad request: Invalid field value; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server or pack not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### GET /servers/{server_id}/addons/custom-packs/{pack_id}/diff — Diff a custom pack Compares a pack against what is currently installed on the server and returns the mods that would be added, removed, or version-changed by an install. **Access** API scope: `servers:addons:read` — List installed addons, search the marketplace, read content details and versions, list software versions, and read custom packs. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id Responses: `200` Pack diff; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server or pack not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/addons/custom-packs/{pack_id}/install — Install a custom pack Installs the pack's mods onto the server's active instance. Runs synchronously and returns the final counts. When the same pack was already installed with the same loader and Minecraft version, only changed mods are synced (`mode: "diff"`); otherwise the loader jar is (re)installed, `/mods` is wiped, and every mod is pulled (`mode: "full"`). **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Pack install result; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server or pack not found; `409` Conflict: Server unavailable; `429` Rate limited; `502` Upstream error: Node could not install the pack; `503` Service unavailable: Marketplace service unavailable ## Custom Pack Items ### POST /servers/{server_id}/addons/custom-packs/{pack_id}/items — Add an item to a pack Adds a mod to a pack, resolving its required dependencies. If the mod is incompatible with the pack's loader/version, the response has `requires_confirmation: true` and the item is not added; resend with `force: true` to add it anyway. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Item added (or confirmation required); `400` Bad request: Invalid source or project id; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server, pack, or project not found; `409` Conflict: Pack item limit reached; `429` Rate limited; `503` Service unavailable: Marketplace service unavailable ### DELETE /servers/{server_id}/addons/custom-packs/{pack_id}/items/{source}/{project_id} — Remove a pack item Removes a mod from a pack. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id - `source` (path, required): Item source (modrinth | curseforge) - `project_id` (path, required): Item project id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Item removed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server, pack, or item not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### PATCH /servers/{server_id}/addons/custom-packs/{pack_id}/items/{source}/{project_id} — Update a pack item Changes the pinned version of a mod already in the pack. **Access** API scope: `servers:addons:write` — Install and toggle addons, install modpacks, and create, edit, and install custom packs. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `pack_id` (path, required): Custom pack id - `source` (path, required): Item source (modrinth | curseforge) - `project_id` (path, required): Item project id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Item updated; `400` Bad request: Invalid version id; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or pack ownership; `404` Not found: Server, pack, or item not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ## Modules ### GET /servers/{server_id}/modules — List declared modules Reads the server's supported project manifests and lists every declared dependency, enriched with the exact installed version (from lockfiles), the latest public registry version, and a vulnerability summary where available. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of modules to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of modules to skip. Defaults to `0`. Responses: `200` Declared modules; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### GET /servers/{server_id}/modules/capabilities — Get module capabilities Detects supported project manifests (`package.json`, `requirements.txt`, `Cargo.toml`, `composer.json`, `go.mod`, and friends) in the server root and reports which package listings and background package-manager mutations are available. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Module capabilities; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### POST /servers/{server_id}/modules/delete — Delete a module Removes a package through the detected package manager. Creates a background task on the server's node and returns it with `status: "queued"`. Uses `POST /modules/delete` (matching `POST /files/delete`) because the module is addressed by the request body, not the path. **Access** API scope: `servers:modules:write` — Install, update, and remove runtime dependency modules. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Module delete task accepted; `400` Bad request: Invalid package-manager request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### POST /servers/{server_id}/modules/install — Install a module Installs a package through the detected package manager. Creates a background task on the server's node and returns it with `status: "queued"`; poll `GET /servers/{server_id}/modules/tasks/{task_id}` for progress. The command runs as argv without a shell. **Access** API scope: `servers:modules:write` — Install, update, and remove runtime dependency modules. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Module install task accepted; `400` Bad request: Invalid package-manager request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### GET /servers/{server_id}/modules/search — Search a package registry Searches the selected package manager's public registry (npm, PyPI, crates.io, Packagist, pkg.go.dev, and friends). The package manager must match a manifest detected on the server. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `package_manager` (query, required): Package manager to search, for example `npm` or `pip`. - `q` (query, required): Search text. - `manifest_path` (query): Manifest path to target when several manifests are detected. - `limit` (query): Maximum results to return (clamped to 1–20, default 10). Responses: `200` Registry search results; `400` Bad request: Invalid registry search request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Registry or server node unreachable ### POST /servers/{server_id}/modules/update — Update a module Updates one package, or every package when `package` is omitted, through the detected package manager. Creates a background task on the server's node and returns it with `status: "queued"`. **Access** API scope: `servers:modules:write` — Install, update, and remove runtime dependency modules. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Module update task accepted; `400` Bad request: Invalid package-manager request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### GET /servers/{server_id}/modules/versions — List registry versions for a package Lists published versions of one package from the package manager's public registry. The package manager must match a manifest detected on the server. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `package_manager` (query, required): Package manager to query, for example `npm` or `pip`. - `package` (query, required): Package name. - `manifest_path` (query): Manifest path to target when several manifests are detected. - `limit` (query): Maximum versions to return (clamped to 1–60, default 25). Responses: `200` Registry package versions; `400` Bad request: Invalid registry version request; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Registry or server node unreachable ## Module Tasks ### GET /servers/{server_id}/modules/tasks — List background module tasks Lists the background package-manager tasks recorded on the server's node. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of tasks to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of tasks to skip. Defaults to `0`. Responses: `200` Background module tasks; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### GET /servers/{server_id}/modules/tasks/{task_id} — Get a background module task Retrieves one background package-manager task by id. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `task_id` (path, required): Module task id Responses: `200` Background module task; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or task not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### DELETE /servers/{server_id}/modules/tasks/{task_id} — Cancel a background module task Cancels a queued or running background package-manager task and returns the task in its post-cancellation state. **Access** API scope: `servers:modules:write` — Install, update, and remove runtime dependency modules. Server access: owner, or server permission `file.update`. Parameters: - `server_id` (path, required): Falix server id - `task_id` (path, required): Module task id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Cancelled background module task; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or task not found; `429` Rate limited; `502` Upstream error: Server node unreachable ### GET /servers/{server_id}/modules/tasks/{task_id}/logs — Get module task logs Returns the retained output of one background package-manager task. Container-runtime noise is filtered out. **Access** API scope: `servers:modules:read` — List installed runtime dependency modules, search the registry, and read module tasks. Server access: owner, or server permission `file.read`. Parameters: - `server_id` (path, required): Falix server id - `task_id` (path, required): Module task id Responses: `200` Background module task logs; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or task not found; `429` Rate limited; `502` Upstream error: Server node unreachable ## Advertisement ### GET /servers/{server_id}/advertisement — Retrieve the advertisement Returns the server's current directory listing (published or unpublished) and the latest moderation revision. Only the server owner can view or manage a server's advertisement. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Advertisement state; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Advertisement service unavailable ### PUT /servers/{server_id}/advertisement — Publish or update the advertisement Publishes or updates a server's public directory listing. Runs the full validation + AI moderation pipeline and always writes an audit revision; the listing is published only on approval. Owner-only; server must be active and not suspended. Accepts bodies up to 8 MB with idempotent retries. **Access** Server access: the server owner only; the server must be active and not suspended. Runs the full validation + AI moderation pipeline; accepts bodies up to 8 MB with idempotent retries. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Submission processed (approved or rejected); `400` Bad request: Invalid advertisement data, or no server subdomain set; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, not the server owner, suspended, or relist-blocked; `409` Conflict: Server unavailable, or slug conflict; `413` Payload too large: Body exceeded 8 MB; `429` Rate limited; `503` Service unavailable: Advertisement or rate-limit service unavailable ### DELETE /servers/{server_id}/advertisement — Unpublish the advertisement Removes the server's listing from the public directory without deleting its revision history. Idempotent: unpublishing an already-unpublished (or never published) listing succeeds and returns the current state. Only the server owner can unpublish. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Advertisement unpublished; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Advertisement or rate-limit service unavailable ## Advertisement Posts ### GET /servers/{server_id}/advertisement/comments — List advertisement comments Returns the comments on the server's public listing page in the moderation view (all statuses, with report counts), newest first. Owner only. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum records to return (1-100). Defaults to 25. - `offset` (query): Records to skip. Defaults to 0. Responses: `200` Comments, newest first; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Advertisement service unavailable ### DELETE /servers/{server_id}/advertisement/comments/{comment_id} — Delete an advertisement comment Permanently removes a comment from the server's public listing page. Owner only. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `comment_id` (path, required): Comment id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Comment deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server or comment not found; `429` Rate limited; `503` Service unavailable: Advertisement service unavailable ### PATCH /servers/{server_id}/advertisement/comments/{comment_id} — Hide or restore an advertisement comment Sets a comment's status to `hidden` or `visible`. Restoring a reported comment resets its report count so it is not immediately re-hidden. Owner only. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `comment_id` (path, required): Comment id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Comment status updated; `400` Bad request: Invalid status value; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server or comment not found; `429` Rate limited; `503` Service unavailable: Advertisement service unavailable ### GET /servers/{server_id}/advertisement/posts — List advertisement posts Returns the blog/update posts on the server's public listing page, any status, newest first. Owner only. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum records to return (1-100). Defaults to 25. - `offset` (query): Records to skip. Defaults to 0. Responses: `200` Posts, newest first; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Advertisement service unavailable ### POST /servers/{server_id}/advertisement/posts — Create an advertisement post Publishes a blog/update post on the server's public listing page. The HTML body is sanitized server-side and the post runs the same fail-closed AI moderation as the dashboard; a rejected post is stored with status `rejected` and only a generic rejection reason. Requires a published listing, and at most 50 posts per server. Owner only; the server must be active and not suspended. Accepts request bodies up to 1 MB with idempotent retries. **Access** Server access: the server owner only; the server must be active and not suspended. The HTML body is sanitized and AI-moderated fail-closed; accepts bodies up to 1 MB with idempotent retries. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Post processed (published or rejected); `400` Bad request: Invalid post data, no published listing, or post limit reached; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, not the server owner, or suspended; `409` Conflict: Server installing or transferring; `413` Payload too large: Body exceeded 1 MB; `429` Rate limited; `503` Service unavailable: Advertisement or rate-limit service unavailable ### PUT /servers/{server_id}/advertisement/posts/{post_id} — Update an advertisement post Replaces a post's title and body. The post is re-sanitized and re-moderated exactly like a new post, and republished only on approval. Owner only; the server must be active and not suspended. Accepts request bodies up to 1 MB with idempotent retries. **Access** Server access: the server owner only; the server must be active and not suspended. The HTML body is re-sanitized and re-moderated; accepts bodies up to 1 MB with idempotent retries. Parameters: - `server_id` (path, required): Falix server id - `post_id` (path, required): Post id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Post processed (published or rejected); `400` Bad request: Invalid post data; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, not the server owner, or suspended; `404` Not found: Server or post not found; `409` Conflict: Server installing or transferring; `413` Payload too large: Body exceeded 1 MB; `429` Rate limited; `503` Service unavailable: Advertisement or rate-limit service unavailable ### DELETE /servers/{server_id}/advertisement/posts/{post_id} — Delete an advertisement post Permanently removes a post from the server's public listing page. Owner only. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `post_id` (path, required): Post id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Post deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, or not the server owner; `404` Not found: Server or post not found; `429` Rate limited; `503` Service unavailable: Advertisement or rate-limit service unavailable ## Allocations ### GET /servers/{server_id}/allocations — List server allocations Returns the ports assigned to a server. The primary allocation is returned first, followed by the remaining allocations sorted by port. **Access** API scope: `servers:network:read` — List server allocations and connection addresses. Server access: owner, or server permission `allocation.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of allocations to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of allocations to skip. Defaults to `0`. Responses: `200` Server allocations; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### POST /servers/{server_id}/allocations — Create server allocation Claims one available allocation on the server's current node. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Allocation created; `400` Bad request: No allocation is available on this node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Allocation limit reached or allocation claim conflict; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### DELETE /servers/{server_id}/allocations/{allocation_id} — Delete server allocation Removes a non-primary allocation from a server and cleans up proxy mappings using that port. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.delete`. Parameters: - `server_id` (path, required): Falix server id - `allocation_id` (path, required): Allocation id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Allocation deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or allocation not found; `409` Conflict: Allocation cannot be deleted in its current state; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### PATCH /servers/{server_id}/allocations/{allocation_id} — Update server allocation Updates allocation notes and/or icon metadata. Send an empty string to clear a field; omit a field to leave it unchanged. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.update`. Parameters: - `server_id` (path, required): Falix server id - `allocation_id` (path, required): Allocation id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Allocation updated; `400` Bad request: Invalid update body; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or allocation not found; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### PUT /servers/{server_id}/allocations/{allocation_id}/primary — Set primary server allocation Makes an existing server allocation the primary connection port. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.update`. Parameters: - `server_id` (path, required): Falix server id - `allocation_id` (path, required): Allocation id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Primary allocation updated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or allocation not found; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ## Ports ### GET /servers/{server_id}/ports — List server ports Returns the ports assigned to a server. The primary port is returned first, followed by the remaining ports sorted by port number. Node-internal addresses are never exposed — connect using each port's `display_address`. **Access** API scope: `servers:network:read` — List server allocations and connection addresses. Server access: owner, or server permission `allocation.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of ports to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of ports to skip. Defaults to `0`. Responses: `200` Server ports; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### POST /servers/{server_id}/ports — Create server port Claims one available port on the server's current node. Premium servers get a higher port limit; hitting the limit returns `409 limit_reached`. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Port created; `400` Bad request: No port is available on this node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Port limit reached or port claim conflict; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### DELETE /servers/{server_id}/ports/{port_id} — Delete server port Removes a non-primary port from a server and cleans up proxy mappings using that port. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.delete`. Parameters: - `server_id` (path, required): Falix server id - `port_id` (path, required): Port id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Port deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or port not found; `409` Conflict: Port cannot be deleted in its current state; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### PATCH /servers/{server_id}/ports/{port_id} — Update server port Updates the port's note. Send an empty string to clear it. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.update`. Parameters: - `server_id` (path, required): Falix server id - `port_id` (path, required): Port id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Port updated; `400` Bad request: Invalid update body; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or port not found; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ### PUT /servers/{server_id}/ports/{port_id}/primary — Set primary server port Makes an existing server port the primary connection port, updating any configured Minecraft DNS records to match. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.update`. Parameters: - `server_id` (path, required): Falix server id - `port_id` (path, required): Port id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Primary port updated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or port not found; `429` Rate limited; `503` Service unavailable: Allocation service unavailable ## Subdomains ### GET /servers/{server_id}/subdomains — List subdomains Returns the server's managed subdomains, usage limits, and the suffixes available for new subdomains. **Access** API scope: `servers:subdomains:read` — List a server's managed subdomains and available suffixes. Server access: owner, or server permission `allocation.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Server subdomains; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Subdomain service unavailable ### POST /servers/{server_id}/subdomains — Create a subdomain Registers a managed subdomain whose DNS A and SRV records point at the given allocation. Plan limits apply (3 subdomains on free, 10 on premium). **Access** API scope: `servers:subdomains:write` — Create, rename, re-point, and delete managed subdomains. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Subdomain created; `400` Bad request: Invalid name, taken hostname, or limit reached; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or allocation not found; `429` Rate limited; `503` Service unavailable: Subdomain service unavailable ### DELETE /servers/{server_id}/subdomains/{hostname} — Delete a subdomain Removes an additional subdomain and its DNS records. The primary subdomain cannot be deleted; set another primary first. **Access** API scope: `servers:subdomains:write` — Create, rename, re-point, and delete managed subdomains. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `hostname` (path, required): Full hostname to delete - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Subdomain deleted; `400` Bad request: Primary subdomain or not a managed subdomain; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or subdomain not found; `429` Rate limited; `503` Service unavailable: Subdomain service unavailable ### PATCH /servers/{server_id}/subdomains/{hostname} — Rename a subdomain Changes a subdomain's label and/or suffix, moving its DNS records. Works for both primary and additional subdomains. **Access** API scope: `servers:subdomains:write` — Create, rename, re-point, and delete managed subdomains. Server access: owner, or server permission `allocation.update`. Parameters: - `server_id` (path, required): Falix server id - `hostname` (path, required): Current full hostname - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Subdomain renamed; `400` Bad request: Invalid or taken name; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or subdomain not found; `429` Rate limited; `503` Service unavailable: Subdomain service unavailable ### PUT /servers/{server_id}/subdomains/{hostname}/primary — Set the primary subdomain Makes a managed subdomain the server's primary address. The previous primary subdomain is kept as an additional subdomain. **Access** API scope: `servers:subdomains:write` — Create, rename, re-point, and delete managed subdomains. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `hostname` (path, required): Full hostname to make primary - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Primary subdomain set; `400` Bad request: Already primary or not a managed subdomain; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or subdomain not found; `429` Rate limited; `503` Service unavailable: Subdomain service unavailable ## Domains ### GET /servers/{server_id}/domains — List custom domains Returns the customer-owned domains attached to the server, with nameserver instructions for any domain that is not yet verified. **Access** API scope: `servers:domains:read` — List a server's custom domains and their verification state. Server access: owner, or server permission `allocation.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Custom domains; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Domain service unavailable ### POST /servers/{server_id}/domains — Add a custom domain Attaches a domain you own to the server and creates its DNS records. The domain must then be verified by pointing its nameservers (or an A record) at Falix. Plan limits apply (3 domains on free, 5 on premium). **Access** API scope: `servers:domains:write` — Add, verify, re-point, and remove customer-owned domains. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Domain added, verification pending; `400` Bad request: Invalid, blocked, in-use, or limit-exceeded domain; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or allocation not found; `429` Rate limited; `503` Service unavailable: Domain service unavailable ### DELETE /servers/{server_id}/domains/{domain_id} — Remove a custom domain Detaches the domain and deletes its DNS records. Deleting the primary domain automatically falls back to a managed subdomain when one exists. **Access** API scope: `servers:domains:write` — Add, verify, re-point, and remove customer-owned domains. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `domain_id` (path, required): Custom domain id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Domain removed; `400` Bad request: Primary domain with no fallback subdomain; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or domain not found; `429` Rate limited; `503` Service unavailable: Domain service unavailable ### PUT /servers/{server_id}/domains/{domain_id}/primary — Set the primary domain Makes a verified custom domain the server's primary address. The previous primary managed subdomain, if any, is kept as an additional subdomain. **Access** API scope: `servers:domains:write` — Add, verify, re-point, and remove customer-owned domains. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `domain_id` (path, required): Custom domain id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Primary domain set; `400` Bad request: Domain unverified or already primary; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or domain not found; `429` Rate limited; `503` Service unavailable: Domain service unavailable ### POST /servers/{server_id}/domains/{domain_id}/verify — Verify a custom domain Checks the domain's live DNS against the expected nameservers (or A record) and marks it verified on success. Returns `409` with setup guidance while DNS is not yet correct. **Access** API scope: `servers:domains:write` — Add, verify, re-point, and remove customer-owned domains. Server access: owner, or server permission `allocation.update`. Parameters: - `server_id` (path, required): Falix server id - `domain_id` (path, required): Custom domain id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Domain verified; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or domain not found; `409` Conflict: DNS is not pointed correctly yet; `429` Rate limited; `503` Service unavailable: Domain service unavailable ## Proxies ### GET /servers/{server_id}/proxies — List proxies Returns the HTTP proxies configured for the server and usage limits. **Access** API scope: `servers:proxies:read` — List a server's HTTP proxies, their SSL state, and limits. Server access: owner, or server permission `proxy.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of proxies to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of proxies to skip. Defaults to `0`. Responses: `200` Server proxies; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Proxy service unavailable ### POST /servers/{server_id}/proxies — Create a proxy Puts an HTTPS reverse proxy in front of a server port, using either a managed `*.falix.org` subdomain or a customer-owned domain. Plan limits apply. **Access** API scope: `servers:proxies:write` — Create, update, delete, and re-issue SSL for HTTP proxies. Server access: owner, or server permission `proxy.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Proxy created; `400` Bad request: Invalid domain, port, or limit reached; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `502` Upstream error: Proxy agent could not apply the config; `503` Service unavailable: Proxy service unavailable ### DELETE /servers/{server_id}/proxies/{proxy_id} — Delete a proxy Removes the proxy from the agent and deletes it. **Access** API scope: `servers:proxies:write` — Create, update, delete, and re-issue SSL for HTTP proxies. Server access: owner, or server permission `proxy.delete`. Parameters: - `server_id` (path, required): Falix server id - `proxy_id` (path, required): Proxy id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Proxy deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or proxy not found; `429` Rate limited; `502` Upstream error: Proxy agent could not remove the config; `503` Service unavailable: Proxy service unavailable ### PATCH /servers/{server_id}/proxies/{proxy_id} — Update a proxy Changes the backend port and/or enabled state, applying the change to the proxy agent with automatic rollback on failure. **Access** API scope: `servers:proxies:write` — Create, update, delete, and re-issue SSL for HTTP proxies. Server access: owner, or server permission `proxy.update`. Parameters: - `server_id` (path, required): Falix server id - `proxy_id` (path, required): Proxy id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Proxy updated; `400` Bad request: Invalid or empty update; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or proxy not found; `429` Rate limited; `502` Upstream error: Proxy agent could not apply the config; `503` Service unavailable: Proxy service unavailable ### POST /servers/{server_id}/proxies/{proxy_id}/retry-ssl — Retry SSL issuance Re-runs certificate issuance for a custom-domain proxy. Managed `*.falix.org` proxies use the wildcard certificate and never need this. **Access** API scope: `servers:proxies:write` — Create, update, delete, and re-issue SSL for HTTP proxies. Server access: owner, or server permission `proxy.update`. Parameters: - `server_id` (path, required): Falix server id - `proxy_id` (path, required): Proxy id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Certificate issued; `400` Bad request: Not a custom-domain proxy; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or proxy not found; `409` Conflict: Certificate issuance failed; `429` Rate limited; `503` Service unavailable: Proxy service unavailable ### GET /servers/{server_id}/proxies/{proxy_id}/status — Get proxy status Returns a proxy's DNS verification and SSL status. For custom domains this re-checks the published TXT record live and advances `verification_status` once the record has propagated. Managed `*.falix.org` proxies always report as verified. **Access** API scope: `servers:proxies:read` — List a server's HTTP proxies, their SSL state, and limits. Server access: owner, or server permission `proxy.read`. Parameters: - `server_id` (path, required): Falix server id - `proxy_id` (path, required): Proxy id Responses: `200` Proxy status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or proxy not found; `429` Rate limited; `503` Service unavailable: Proxy service unavailable ### POST /servers/{server_id}/proxies/{proxy_id}/verify — Verify a proxy domain Starts (or restarts) DNS ownership verification for a custom-domain proxy and returns the TXT record to publish. Managed `*.falix.org` proxies are verified automatically and reject this call. Publish the returned record, then poll the status endpoint until `verification_status` is `verified`. **Access** API scope: `servers:proxies:write` — Create, update, delete, and re-issue SSL for HTTP proxies. Server access: owner, or server permission `proxy.create`. Parameters: - `server_id` (path, required): Falix server id - `proxy_id` (path, required): Proxy id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Verification started; `400` Bad request: Not a custom-domain proxy or invalid domain; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or proxy not found; `429` Rate limited; `503` Service unavailable: Proxy service unavailable ## Internal Network ### GET /servers/{server_id}/internal-network — Retrieve internal network state Returns whether internal networking is enabled, the server's internal address, connected peers, and (with the manage permission) linkable candidates. **Access** API scope: `servers:network:read`. Server access: owner, or server permission `allocation.read`. Candidate peers are only listed when the caller also holds `allocation.internal-network`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Internal network state; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Network service unavailable ### PUT /servers/{server_id}/internal-network — Update internal network state Enables or disables internal networking (allocating or releasing the internal IP) and toggles internal-only port mode. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Internal network updated; `400` Bad request: Empty body, unsupported node, or invalid transition; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Network service unavailable ### POST /servers/{server_id}/internal-network/peers — Connect a peer Links another of your servers to this server's internal network. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.internal-network`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Peer connected; `400` Bad request: Internal networking disabled or invalid peer; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or peer not found; `429` Rate limited; `503` Service unavailable: Network service unavailable ### DELETE /servers/{server_id}/internal-network/peers/{peer_uuid} — Disconnect a peer Removes a peer from this server's internal network. **Access** API scope: `servers:network:write` — Create, update, and delete server allocations. Server access: owner, or server permission `allocation.internal-network`. Parameters: - `server_id` (path, required): Falix server id - `peer_uuid` (path, required): Peer server UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Peer removed; `400` Bad request: Invalid peer; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or peer not found; `429` Rate limited; `503` Service unavailable: Network service unavailable ## Firewall ### GET /servers/{server_id}/firewall — Get the firewall configuration Returns the authoritative firewall state and rules from the panel store, together with the server's allocated ports for port-rule validation. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Firewall configuration; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Firewall service unavailable ### POST /servers/{server_id}/firewall/rules — Add a firewall rule Appends the rule to the authoritative ruleset and pushes it to the server node. Returns the updated firewall configuration. **Access** Restricted (VPN-flagged) accounts cannot modify firewall rules. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Rule added; `400` Bad request: Rule rejected by the node or rule limit reached; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or restricted account; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Firewall service unavailable ### PUT /servers/{server_id}/firewall/rules/{rule_id} — Update a firewall rule Replaces a rule (preserving its id and creation time) and pushes the updated ruleset to the server node. Returns the updated firewall configuration. **Access** Restricted (VPN-flagged) accounts cannot modify firewall rules. Parameters: - `server_id` (path, required): Falix server id - `rule_id` (path, required): Firewall rule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Rule updated; `400` Bad request: Rule rejected by the node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or restricted account; `404` Not found: Server or rule not found; `429` Rate limited; `503` Service unavailable: Firewall service unavailable ### DELETE /servers/{server_id}/firewall/rules/{rule_id} — Delete a firewall rule Removes a rule from the authoritative ruleset and pushes the updated configuration to the server node. **Access** Restricted (VPN-flagged) accounts cannot modify firewall rules. Parameters: - `server_id` (path, required): Falix server id - `rule_id` (path, required): Firewall rule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Rule deleted; `400` Bad request: Rejected by the node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or restricted account; `404` Not found: Server or rule not found; `429` Rate limited; `503` Service unavailable: Firewall service unavailable ### POST /servers/{server_id}/firewall/sync — Sync the firewall to the node Re-pushes the authoritative ruleset to the server node, forcing it to re-apply the full firewall configuration. **Access** Restricted (VPN-flagged) accounts cannot modify firewall rules. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Firewall synced; `400` Bad request: Rejected by the node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or restricted account; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Firewall service unavailable ### POST /servers/{server_id}/firewall/toggle — Toggle the firewall Enables or disables the firewall and/or sets the default action, then pushes the updated ruleset to the server node. **Access** Restricted (VPN-flagged) accounts cannot modify firewall rules. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Firewall toggled; `400` Bad request: Invalid default_action or rejected by the node; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, permission, or restricted account; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Firewall service unavailable ## Firewall Analytics ### GET /servers/{server_id}/firewall/analytics/anomalies — Firewall analytics anomalies Detected traffic anomalies with severity, observed value, and threshold. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics anomalies; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/classes — Firewall analytics by traffic class Connection counts and classifier confidence grouped by traffic class. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics traffic classes; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/countries — Firewall analytics by country Connection counts grouped by source country over the requested range. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics countries; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/export — Export the firewall analytics report Same combined report as `GET /firewall/analytics/report`, returned as a downloadable `application/json` attachment. **Access** Returns the combined analytics report as a downloadable JSON attachment. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. - `limit` (query): Maximum number of source rows to return (clamped to 1–500). Responses: `200` Firewall analytics report download; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/ports — Firewall analytics by port Connection and byte counters grouped by destination port and protocol. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics ports; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/protocols — Firewall analytics by protocol Connection and byte counters grouped by transport protocol. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics protocols; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/report — Firewall analytics report The combined analytics report: summary plus every dimension (countries, sources, ports, protocols, states, classes, anomalies, rule hits). **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. - `limit` (query): Maximum number of source rows to return (clamped to 1–500). Responses: `200` Firewall analytics report; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/rules — Firewall analytics rule hits Packet and byte counters per firewall rule id and action. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics rule hits; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/sources — Firewall analytics by source Top source IPs with geo/ASN metadata and connection/byte counters. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. - `limit` (query): Maximum number of source rows to return (clamped to 1–500). Responses: `200` Firewall analytics sources; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/states — Firewall analytics by connection state Connection and byte counters grouped by conntrack state. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics connection states; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ### GET /servers/{server_id}/firewall/analytics/summary — Firewall analytics summary Time series for network throughput, active connections, and unique sources/countries over the requested range. **Access** API scope: `servers:firewall:read` — Read firewall rules, state, and traffic analytics. Server access: owner, or server permission `firewall.read`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time-range window. One of `15m`, `1h`, `6h`, `24h`, `3d`, `7d`, `30d`. Responses: `200` Firewall analytics summary; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Analytics service unavailable ## Databases ### GET /servers/{server_id}/databases — List server databases Returns database connection metadata for a server. Passwords are not returned from list responses; create or rotate a database password to receive a new plaintext password. **Access** API scope: `servers:databases:read` — List server databases and read connection details. Server access: owner, or server permission `database.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of databases to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of databases to skip. Defaults to `0`. Responses: `200` Server databases; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/databases — Create server database Creates a database on an available database host for the server's node. The plaintext password is returned only in this response. **Access** API scope: `servers:databases:write` — Create and delete server databases and rotate passwords. Server access: owner, or server permission `database.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Database created; `400` Bad request: Invalid request or database limit reached; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Database host unavailable ### GET /servers/{server_id}/databases/{database_id} — Retrieve server database Returns connection metadata for one server database. Passwords are not returned from retrieve responses. **Access** API scope: `servers:databases:read` — List server databases and read connection details. Server access: owner, or server permission `database.read`. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id Responses: `200` Server database; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or database not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### DELETE /servers/{server_id}/databases/{database_id} — Delete server database Deletes a database and its database user from the backing database host. **Access** API scope: `servers:databases:write` — Create and delete server databases and rotate passwords. Server access: owner, or server permission `database.delete`. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Database deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or database not found; `429` Rate limited; `503` Service unavailable: Database host unavailable ### POST /servers/{server_id}/databases/{database_id}/rotate-password — Rotate server database password Generates a new database password and returns it in the response. Existing passwords are never returned by list or retrieve endpoints. **Access** API scope: `servers:databases:write` — Create and delete server databases and rotate passwords. Server access: owner, or server permission `database.update`. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Password rotated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or database not found; `429` Rate limited; `503` Service unavailable: Database host unavailable ## Database Backups ### GET /servers/{server_id}/databases/{database_id}/backups — List database backups Returns the backups stored for one database on the server. The per-database backup limit is reported in `limits`. **Access** Also requires the `database.read` server permission. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `limit` (query): Maximum number of backups to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of backups to skip. Defaults to `0`. Responses: `200` Database backups; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or database not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/databases/{database_id}/backups — Create a database backup Backs up one database and returns the backup in its `creating` state. Poll `GET /servers/{server_id}/databases/{database_id}/backups` until the backup's `status` becomes `completed`. Databases whose backups are stored on Google Drive (free plans) can only be backed up from the dashboard. **Access** Also requires the `database.read` server permission. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Database backup started; `400` Bad request: Backups disabled or cloud-only storage; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server or database not found; `409` Conflict: Database backup limit reached; `429` Rate limited; `502` Upstream error: Node could not start the backup ### DELETE /servers/{server_id}/databases/{database_id}/backups/{backup_uuid} — Delete a database backup Permanently deletes a database backup. Locally stored (`falcon`/`borg`) archives are also removed from the node. Google Drive files are cleaned up by the dashboard/orphan job — the public API only drops the record. **Access** Also requires the `database.read` server permission. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `backup_uuid` (path, required): Database backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Database backup deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Database backup not found; `429` Rate limited; `502` Upstream error: Node could not delete the backup; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/databases/{database_id}/backups/{backup_uuid}/download — Create a database backup download URL Returns a short-lived signed URL for downloading a completed database backup directly from the node. Google Drive backups are dashboard-only. **Access** Also requires the `database.read` server permission. Addressed by database id and backup UUID; the owning server is resolved automatically. Google Drive backups are dashboard-only. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `backup_uuid` (path, required): Database backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Signed download URL; `400` Bad request: Cloud backup download not supported; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Database backup or node not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/databases/{database_id}/backups/{backup_uuid}/restore — Restore a database backup Restores a completed backup over the live database, overwriting its current contents, and returns `202 Accepted` once the node has accepted the restore. Google Drive backups are dashboard-only. This is a destructive operation. It is gated by the `servers:databases:write` scope; a future revision may promote it to a dedicated dangerous scope, as server file-backup restores use `servers:backups:restore`. **Access** Also requires the `database.update` server permission. Destructive: overwrites the live database. Uses the `servers:databases:write` scope; a future revision may promote it to a dedicated dangerous scope, mirroring the file-backup `servers:backups:restore` pattern. Google Drive backups are dashboard-only. Parameters: - `server_id` (path, required): Falix server id - `database_id` (path, required): Database id - `backup_uuid` (path, required): Database backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Database restore started; `400` Bad request: Cloud backup restore not supported; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Database backup not found; `429` Rate limited; `502` Upstream error: Node could not start the restore ## Backups ### GET /servers/{server_id}/backups — List server backups Returns the server's backups newest-first, in pages of up to 100 (default 25). Use `limit` and `offset` to page; `pagination` echoes the applied window and total count. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Server backups; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### POST /servers/{server_id}/backups — Create a backup Starts a new backup and returns `202 Accepted` with the backup in its `creating` state. Poll `GET /servers/{server_id}/backups/{backup_uuid}` until `status` becomes `completed`. Backups on free (Google Drive) nodes are dashboard-only; the public API creates local (`falcon`/`borg`) backups. **Access** API scope: `servers:backups:write` — Create, delete, lock, and unlock server backups. Server access: owner, or server permission `backup.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Backup creation started; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or server suspended; `404` Not found: Server not found; `409` Conflict: Backup limit reached, cooldown active, or server unavailable; `429` Rate limited; `502` Upstream error: Node could not start the backup ### GET /servers/{server_id}/backups/{backup_uuid} — Retrieve a backup Returns metadata for a single backup by UUID. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID Responses: `200` Server backup; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or backup not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### DELETE /servers/{server_id}/backups/{backup_uuid} — Delete a backup Permanently deletes a backup. Locked backups must be unlocked first. **Access** API scope: `servers:backups:write` — Create, delete, lock, and unlock server backups. Server access: owner, or server permission `backup.delete`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Backup deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or backup not found; `409` Conflict: Backup is locked or server unavailable; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### POST /servers/{server_id}/backups/{backup_uuid}/download — Create a backup download URL Returns a short-lived signed URL for downloading a backup directly from the node. Google Drive and S3 backups are dashboard-only. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Signed download URL; `400` Bad request: Cloud backup download not supported; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, backup, or node not found; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### POST /servers/{server_id}/backups/{backup_uuid}/lock — Lock a backup Locks a backup so it cannot be deleted or rotated out. **Access** API scope: `servers:backups:write` — Create, delete, lock, and unlock server backups. Server access: owner, or server permission `backup.update`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Backup locked; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or backup not found; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### POST /servers/{server_id}/backups/{backup_uuid}/transfer — Transfer a backup to another server Moves a backup's ownership from the source server (in the path) to a target server you own (in the body); the move completes before the response. Authorizes both servers: the source with `servers:backups:read` (and you must own it), and the target with `servers:backups:write`. Locked backups cannot be transferred, and the target must be under its backup limit and not in storage mode. **Access** Authorizes two servers. Source: `servers:backups:read` and you must own it. Target (`target_server_id` in the body): `servers:backups:write` and the `backup.create` server permission. Parameters: - `server_id` (path, required): Source Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Backup transferred; `400` Bad request: Invalid UUID, locked backup, or same server; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or not the source owner; `404` Not found: Backup or target server not found; `409` Conflict: Target is in storage mode or at its backup limit; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### POST /servers/{server_id}/backups/{backup_uuid}/unlock — Unlock a backup Unlocks a backup so it can be deleted or rotated out. **Access** API scope: `servers:backups:write` — Create, delete, lock, and unlock server backups. Server access: owner, or server permission `backup.update`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Backup unlocked; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or backup not found; `429` Rate limited; `503` Service unavailable: Backup service unavailable ## Backup Restore ### GET /servers/{server_id}/backups/scheduled/{backup_uuid}/restore-points — List restore points Returns the node-reported restore point history for a scheduled backup. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Scheduled backup UUID Responses: `200` Restore points; `400` Bad request: Invalid backup UUID; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Scheduled backup not found; `429` Rate limited; `502` Upstream error: Server node request failed ### GET /servers/{server_id}/backups/{backup_uuid}/browse — Browse a backup archive Lists directory entries within a backup at a given path. Works for both user-created and scheduled backups. While the archive is still being indexed the response reports `status: "indexing"` with an empty listing — retry shortly. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `path` (query): Directory path within the backup. Defaults to `/`. Responses: `200` Directory listing; `400` Bad request: Path contains traversal sequences; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Backup not found; `429` Rate limited; `502` Upstream error: Server node request failed ### GET /servers/{server_id}/backups/{backup_uuid}/contents — List backup contents Lists the top-level files contained in a completed backup. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID Responses: `200` Backup contents; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Backup not found or not completed; `429` Rate limited; `502` Upstream error: Server node request failed ### POST /servers/{server_id}/backups/{backup_uuid}/copy-to-server — Copy files from a backup onto the server Extracts selected files from a backup into the server's live filesystem at `destination`. The node performs the copy before responding; the response reports how many files were copied. Because it writes files, it requires both the `servers:backups:read` and `servers:files:write` scopes and the `backup.read` and `file.create` server permissions. **Access** Writes files to the live server, so it also requires the `servers:files:write` API scope and the `file.create` server permission. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files copied; `400` Bad request: Invalid paths or missing fields; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Backup not found or not stored locally; `429` Rate limited; `502` Upstream error: Server node request failed ### POST /servers/{server_id}/backups/{backup_uuid}/quick-restore — Quick-restore files from a backup Restores selected files from a completed backup into the live server, without truncating the destination. The node performs the restore before responding, so a `200` means the files are in place. Requires the destructive `servers:backups:restore` scope (never granted by `servers:*`). **Access** API scope: `servers:backups:restore` — a destructive scope that is never granted by the `servers:*` wildcard and must be granted explicitly (or via `*`). Server access: owner, or server permission `backup.restore`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files restored; `400` Bad request: No paths selected or invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Backup not found or not stored locally; `409` Conflict: Server is not in a restorable state; `429` Rate limited; `502` Upstream error: Node could not restore the files ### POST /servers/{server_id}/backups/{backup_uuid}/restore — Restore a backup Restores an entire backup and returns `202 Accepted`. The server moves to the `restoring_backup` state — poll `GET /servers/{server_id}/status` until `lifecycle_status` clears. The server must be idle (no other operation in progress). Requires the destructive `servers:backups:restore` scope, which is never granted by a `servers:*` wildcard. Google Drive restores are dashboard-only. **Access** API scope: `servers:backups:restore` — a destructive scope that is never granted by the `servers:*` wildcard and must be granted explicitly (or via `*`). Server access: owner, or server permission `backup.restore`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Backup restore started; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or backup not found; `409` Conflict: Server is not in a restorable state; `429` Rate limited; `502` Upstream error: Node could not start the restore ### POST /servers/{server_id}/backups/{backup_uuid}/restore/selective — Selectively restore files from a backup Restores a chosen set of files from a completed backup, optionally clearing the destination first (`truncate: true`). The node performs the restore before responding, so a `200` means the files are in place. Requires the destructive `servers:backups:restore` scope (never granted by `servers:*`). **Access** API scope: `servers:backups:restore` — a destructive scope that is never granted by the `servers:*` wildcard and must be granted explicitly (or via `*`). Server access: owner, or server permission `backup.restore`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Files restored; `400` Bad request: No paths selected or invalid path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Backup not found or not completed; `409` Conflict: Server is not in a restorable state; `429` Rate limited; `502` Upstream error: Node could not restore the files ## Auto Backups ### GET /servers/{server_id}/backups/auto-settings — Get auto-backup settings Returns the server's automatic (pre-offload) backup configuration. When no configuration exists, defaults are returned (disabled, keep 3). **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Auto-backup settings; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### PATCH /servers/{server_id}/backups/auto-settings — Update auto-backup settings Enables or disables automatic pre-offload backups and sets how many to retain (`1`–`10`). Enabling requires a linked Google Drive account. Servers on storage-mode nodes cannot run automatic backups. **Access** Enabling automatic backups requires a linked Google Drive account. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Settings updated; `400` Bad request: Invalid retention value; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server is in storage mode; `412` Integration required: No Google Drive account is connected; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### GET /servers/{server_id}/backups/scheduled — List scheduled backups Lists a server's automatic (scheduled) backups, kept separately from user-created backups, newest-first in pages of up to 100 (default 25). Use `limit` and `offset` to page; `pagination` echoes the applied window and total count. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Scheduled backups; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### GET /servers/{server_id}/backups/scheduled/{backup_uuid} — Retrieve scheduled backup details Returns node-reported details for a single scheduled backup by UUID. **Access** API scope: `servers:backups:read` — List and inspect server backups and generate backup download URLs. Server access: owner, or server permission `backup.read`. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Scheduled backup UUID Responses: `200` Scheduled backup details; `400` Bad request: Invalid backup UUID; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Scheduled backup not found; `429` Rate limited; `502` Upstream error: Server node request failed ## Google Drive Backups ### GET /servers/{server_id}/backups/gdrive — List Google Drive backups Lists the server's backups that are stored on Google Drive, newest-first in pages of up to 100 (default 25). Requires a linked Google Drive account. Use `limit` and `offset` to page; `pagination` echoes the applied window and total count. **Access** Requires a linked Google Drive account. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of records to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of records to skip. Defaults to `0`. Responses: `200` Google Drive backups; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `412` Integration required: No Google Drive account is connected; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### POST /servers/{server_id}/backups/gdrive/link-backup — Link a Google Drive backup Links an orphaned Google Drive backup file (a `{uuid}.tar.gz`) back to this server by creating a backup record for it. The file must exist in the account's Drive and not already be linked. **Access** Requires the `database.create` server permission. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Backup linked; `400` Bad request: Missing file id or invalid file; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `409` Conflict: File is already linked to a server; `412` Integration required: No Google Drive account is connected; `422` Validation: Google Drive authentication failed; `429` Rate limited; `503` Service unavailable: Backup service unavailable ### GET /servers/{server_id}/backups/gdrive/orphans — List orphaned Google Drive backups Lists Google Drive backup files across the account's linked drives that have no corresponding backup record on any of the account's servers. Google account emails are masked. **Access** Requires a linked Google Drive account. Account emails are masked. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Orphaned Google Drive backups; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `412` Integration required: No Google Drive account is connected; `429` Rate limited; `503` Service unavailable: Google Drive is unavailable ### GET /servers/{server_id}/backups/gdrive/quota — Get Google Drive quota Reports whether the account has a linked Google Drive and, if so, the aggregated storage usage across its drives. Unlike the other Drive endpoints this returns `connected: false` (rather than a precondition error) when no Drive is linked, so it can be used as a status probe. **Access** No server permission is required. Returns `connected: false` rather than an error when no Drive is linked. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Google Drive quota; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server access; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Google Drive is unavailable ### POST /servers/{server_id}/backups/{backup_uuid}/gdrive-download — Create a Google Drive backup download URL Returns a short-lived signed URL for downloading a Google-Drive-stored backup through the Falix proxy (the node cannot attach Drive credentials to a direct link). Mirrors the local-backup download shape. **Access** Requires the `file.read` server permission. Parameters: - `server_id` (path, required): Falix server id - `backup_uuid` (path, required): Backup UUID - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Signed download URL; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Backup not found or not on Google Drive; `412` Integration required: No Google Drive account is connected; `429` Rate limited; `503` Service unavailable: Download proxy is unavailable ## Schedules ### GET /servers/{server_id}/schedules — List schedules Returns every schedule configured for the server, with task and trigger counts. **Access** API scope: `servers:schedules:read` — List schedules, read schedule details, and read execution logs. Server access: owner, or server permission `schedule.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Maximum number of schedules to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of schedules to skip. Defaults to `0`. Responses: `200` Server schedules; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### POST /servers/{server_id}/schedules — Create a schedule Creates a schedule from a name and cron fields. Free-plan owners always run tasks online-only; premium owners may set `only_when_online: false`. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.create`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Schedule created; `400` Bad request: Invalid name, cron expression, or trigger type; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### GET /servers/{server_id}/schedules/timezone — Get schedule timezone Returns the API key owner's preferred IANA timezone, used to compute schedule next-run times. `timezone` is absent when none has been set. **Access** API scope: `servers:schedules:read`. Server access: owner, or any subuser with access to the server — reading your own timezone needs no specific server permission, matching the dashboard. The timezone belongs to the API key's owner. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Timezone preference; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server access; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### PUT /servers/{server_id}/schedules/timezone — Set schedule timezone Sets the API key owner's preferred IANA timezone. The value is validated against the IANA timezone database. Returns the stored timezone. **Access** API scope: `servers:schedules:write`. Server access: owner, or any subuser with access to the server — setting your own timezone needs no specific server permission, matching the dashboard. The timezone belongs to the API key's owner. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Timezone saved; `400` Bad request: Missing or invalid timezone; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server access; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### GET /servers/{server_id}/schedules/{schedule_id} — Retrieve a schedule Returns the schedule with its tasks (in execution order) and event triggers. **Access** API scope: `servers:schedules:read` — List schedules, read schedule details, and read execution logs. Server access: owner, or server permission `schedule.read`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id Responses: `200` Schedule details; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### DELETE /servers/{server_id}/schedules/{schedule_id} — Delete a schedule Deletes the schedule and all of its tasks. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.delete`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Schedule deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### PATCH /servers/{server_id}/schedules/{schedule_id} — Update a schedule Applies any subset of name, cron fields, active state, online-only behavior, and trigger type. Pause or resume a schedule by sending `{"is_active": false}` or `{"is_active": true}`. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Schedule updated; `400` Bad request: Invalid or empty update body; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### GET /servers/{server_id}/schedules/{schedule_id}/logs — List schedule execution logs Returns the schedule's execution history, newest first. **Access** API scope: `servers:schedules:read` — List schedules, read schedule details, and read execution logs. Server access: owner, or server permission `schedule.read`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `limit` (query): Maximum log events to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of log events to skip. Defaults to `0`. Responses: `200` Execution logs; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### POST /servers/{server_id}/schedules/{schedule_id}/run — Run a schedule now Queues the schedule's first task for immediate execution. Returns `409` if the schedule is already running and `400` if it has no tasks. **Access** API scope: `servers:schedules:write`. Server access: owner, or server permission `schedule.read` — the dashboard's run-now button requires only read permission, and the public API mirrors that. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Schedule execution queued; `400` Bad request: Schedule has no tasks; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `409` Conflict: Schedule is already running; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ## Schedule Tasks ### POST /servers/{server_id}/schedules/{schedule_id}/tasks — Add a task Appends a task to the end of the schedule's execution order. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Task created; `400` Bad request: Invalid action or payload; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### POST /servers/{server_id}/schedules/{schedule_id}/tasks/reorder — Reorder tasks Replaces the schedule's task execution order. Send every task id in the desired order. Returns the tasks in their new order. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Tasks reordered; `400` Bad request: Empty task_ids array; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### DELETE /servers/{server_id}/schedules/{schedule_id}/tasks/{task_id} — Delete a task Deletes the task and resequences the schedule's remaining tasks. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `task_id` (path, required): Task id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Task deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, schedule, or task not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### PATCH /servers/{server_id}/schedules/{schedule_id}/tasks/{task_id} — Update a task Applies any subset of action, payload, and time offset to a task. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `task_id` (path, required): Task id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Task updated; `400` Bad request: Invalid action or payload; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, schedule, or task not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ## Schedule Triggers ### GET /servers/{server_id}/schedules/event-types — List trigger event types Returns the static catalog of event types a schedule trigger can listen for, with labels, categories, and — where applicable — the config field schema. **Access** API scope: `servers:schedules:read`. Server access: owner, or any subuser with access to the server — the event-type catalog is static and needs no specific server permission. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Trigger event-type catalog; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server access; `404` Not found: Server not found; `429` Rate limited ### GET /servers/{server_id}/schedules/{schedule_id}/triggers — List event triggers Returns the schedule's event triggers. **Access** API scope: `servers:schedules:read` — List schedules, read schedule details, and read execution logs. Server access: owner, or server permission `schedule.read`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `limit` (query): Maximum number of triggers to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of triggers to skip. Defaults to `0`. Responses: `200` Event triggers; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### POST /servers/{server_id}/schedules/{schedule_id}/triggers — Add an event trigger Starts the schedule when the given event occurs. Valid event types: `server.started`, `server.stopped`, `server.crashed`, `backup.completed`, `player.joined`, `player.left`, `server.idle`, `threshold.cpu`, `threshold.memory`, `threshold.disk`, and `git.deployment.completed`. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Trigger created; `400` Bad request: Invalid event type; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### DELETE /servers/{server_id}/schedules/{schedule_id}/triggers/{trigger_id} — Remove an event trigger Deletes an event trigger from a schedule. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `trigger_id` (path, required): Trigger id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Trigger deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, schedule, or trigger not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### PATCH /servers/{server_id}/schedules/{schedule_id}/triggers/{trigger_id} — Update an event trigger Enables or disables an event trigger. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `trigger_id` (path, required): Trigger id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Trigger updated; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, schedule, or trigger not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ## Schedule Webhooks ### GET /servers/{server_id}/schedules/{schedule_id}/webhooks — List webhooks Returns the schedule's webhooks with masked URLs. **Access** API scope: `servers:schedules:read` — List schedules, read schedule details, and read execution logs. Server access: owner, or server permission `schedule.read`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `limit` (query): Maximum number of webhooks to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of webhooks to skip. Defaults to `0`. Responses: `200` Schedule webhooks; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### POST /servers/{server_id}/schedules/{schedule_id}/webhooks — Add a webhook Registers an HTTPS webhook notified about schedule execution events. The URL is stored server-side and always returned masked. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Webhook created; `400` Bad request: Invalid webhook URL; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server or schedule not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ### DELETE /servers/{server_id}/schedules/{schedule_id}/webhooks/{webhook_id} — Remove a webhook Deletes a webhook from a schedule. **Access** API scope: `servers:schedules:write` — Create, update, delete, and run schedules, and manage their tasks, event triggers, and webhooks. Server access: owner, or server permission `schedule.update`. Parameters: - `server_id` (path, required): Falix server id - `schedule_id` (path, required): Schedule id - `webhook_id` (path, required): Webhook id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Webhook deleted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server, schedule, or webhook not found; `429` Rate limited; `503` Service unavailable: Schedule service unavailable ## Git ### GET /servers/{server_id}/git — Get git integration status Reports per-provider OAuth connection status, the linked repository (with its deploy settings, never its webhook secret), and the schedules available for post-deploy triggering. This is the endpoint for discovering connection state, so it does not require a linked repository. **Access** API scope: `servers:git:read` — Read linked repository status, branches, commits, file trees, and deployment history. Server access: owner, or server permission `git.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Git integration status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/git/link — Link a git repository Associates a git repository with the server for deployments. Only one repository can be linked at a time. For the `public` provider the supplied clone URL is vetted against the SSRF egress guard before storing; connected providers install a push webhook. Rate limited. **Access** For the `public` provider, the clone URL is vetted against the SSRF egress guard before storing. Restricted (VPN) accounts are rejected. Rate limited. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Repository linked; `400` Bad request: Invalid input, blocked clone URL, or repo already linked; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or restricted account; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Database service unavailable ### DELETE /servers/{server_id}/git/link — Unlink a git repository Removes the git repository association from the server, including all deployment settings, and deletes the provider-side push webhook when one was installed. Rate limited. **Access** Requires a linked repository (`412` otherwise). Restricted (VPN) accounts are rejected. Rate limited. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Repository unlinked; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or restricted account; `404` Not found: Server not found; `409` Conflict: Server unavailable; `412` Integration required: No repository linked; `429` Rate limited; `503` Service unavailable: Database service unavailable ### PATCH /servers/{server_id}/git/settings — Update git settings Updates any combination of branch, auto-deploy, restart-on-deploy, sync paths, post-deploy action, post-deploy commands (max 20, each ≤ 500 chars), and post-deploy schedules (max 10). Only provided fields change. **Access** Requires a linked repository (`412` otherwise). Restricted (VPN) accounts are rejected. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Settings updated; `400` Bad request: Invalid sync paths, commands, branch, action, or schedules; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or restricted account; `404` Not found: Server not found; `409` Conflict: Server unavailable; `412` Integration required: No repository linked; `429` Rate limited; `503` Service unavailable: Database service unavailable ### POST /servers/{server_id}/git/validate-public — Validate a public repository Checks that a public repository URL (or provider/owner/repo) is accessible and extracts owner, repo, and default branch. Does not require a linked repository or connected provider. Owner/repo values are validated before any provider API URL is built, and the call is rate limited. **Access** Does not require a linked repository or connected provider. Owner/repo input is validated before any provider API call, and the endpoint is rate limited. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Validation result; `400` Bad request: Invalid or unparseable URL / owner / repo; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ## Git Repository ### GET /servers/{server_id}/git/branches — List repository branches Returns branches from the specified provider repository. Private repos require a connected provider account (`412` otherwise); pass `is_public=true` to list a public repository without an OAuth token. **Access** Private repositories require a connected provider OAuth account; pass `is_public=true` to list a public repository without one. Parameters: - `server_id` (path, required): Falix server id - `provider` (query, required): Provider - `owner` (query, required): Repository owner - `repo` (query, required): Repository name - `is_public` (query): Whether the repository is public - `default_branch` (query): Hint for the default branch Responses: `200` Branch list; `400` Bad request: Invalid provider; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `412` Integration required: Provider account not connected; `429` Rate limited; `503` Service unavailable: Provider API unavailable ### GET /servers/{server_id}/git/commits — List commit history Returns commits (newest first) for the linked repository's branch, or for the supplied `ref`/`path`, paginated with `page` (1-based) and `limit` (default 20, max 100). NOTE: Unlike the standard `limit`/`offset` list contract used elsewhere in the public API, commit history is paged with `page`/`limit`. The git provider's API pages this data upstream, so an arbitrary record `offset` cannot be honored; this endpoint intentionally differs. **Access** API scope: `servers:git:read` — Read linked repository status, branches, commits, file trees, and deployment history. Server access: owner, or server permission `git.read`. Parameters: - `server_id` (path, required): Falix server id - `ref` (query): Branch or ref (defaults to the linked branch) - `path` (query): Restrict history to a path - `page` (query): Page number (1-based) - `limit` (query): Page size (default 20, max 100) Responses: `200` Commit list; `400` Bad request: Invalid ref or path; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `412` Integration required: No repository linked or provider disconnected; `429` Rate limited; `503` Service unavailable: Provider API unavailable ### GET /servers/{server_id}/git/file — Read a single file Returns base64-encoded file bytes at `path` and `ref` (default linked branch), with `is_binary` and `too_large` hints. Files over 1 MiB are reported as `too_large` with no content. **Access** API scope: `servers:git:read` — Read linked repository status, branches, commits, file trees, and deployment history. Server access: owner, or server permission `git.read`. Parameters: - `server_id` (path, required): Falix server id - `ref` (query): Ref (defaults to the linked branch) - `path` (query, required): File path from the repo root (required) Responses: `200` File content; `400` Bad request: Invalid ref/path or path is a directory; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found or file not found; `412` Integration required: No repository linked or provider disconnected; `429` Rate limited; `503` Service unavailable: Provider API unavailable ### GET /servers/{server_id}/git/overview — Get the repository overview Returns the linked repository's identity, description, topics, language breakdown, latest commit, README, and the live-vs-tip deploy state. Best-effort: a provider sub-call that fails degrades that field rather than failing the page. **Access** API scope: `servers:git:read` — Read linked repository status, branches, commits, file trees, and deployment history. Server access: owner, or server permission `git.read`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Repository overview; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `412` Integration required: No repository linked or provider disconnected; `429` Rate limited; `503` Service unavailable: Provider API unavailable ### GET /servers/{server_id}/git/repos — List provider repositories Returns repositories from the specified OAuth provider for the API key owner. Requires a connected provider account (`412` otherwise); the generic `public` provider is not a real account and is rejected. **Access** Requires a connected provider OAuth account. Connect it from the dashboard first; the API returns `412 integration_not_connected` otherwise. Parameters: - `server_id` (path, required): Falix server id - `provider` (query, required): Provider (github, gitlab, codeberg, bitbucket) Responses: `200` Repository list; `400` Bad request: Invalid or unsupported provider; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `412` Integration required: Provider account not connected; `429` Rate limited; `503` Service unavailable: Provider API unavailable ### GET /servers/{server_id}/git/tree — List a repository directory Returns the entries (directories first, then files, alphabetically) of one directory level at `path` (default repo root) and `ref` (default linked branch). **Access** API scope: `servers:git:read` — Read linked repository status, branches, commits, file trees, and deployment history. Server access: owner, or server permission `git.read`. Parameters: - `server_id` (path, required): Falix server id - `ref` (query): Ref (defaults to the linked branch) - `path` (query): Directory path (defaults to repo root) Responses: `200` Directory entries; `400` Bad request: Invalid ref/path or not a directory; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found or path not found; `412` Integration required: No repository linked or provider disconnected; `429` Rate limited; `503` Service unavailable: Provider API unavailable ## Git Deployments ### POST /servers/{server_id}/git/deploy — Deploy from git Triggers a manual deployment: creates a deployment record and instructs the node to sync from the linked repository, applying the configured branch, restart flag, post-deploy action, and post-deploy commands. The deployment runs asynchronously, so this returns `202 Accepted` with the created `deployment_id`; poll `GET /servers/{server_id}/git/deployments` for its progress and final status. Rate limited. Dangerous: requires the `servers:git:deploy` scope, which replaces files on the server and runs post-deploy commands. **Access** API scope: `servers:git:deploy` (dangerous — never granted by the `servers:*` wildcard). Replaces files on the server and runs post-deploy commands. Requires a linked repository (`412` otherwise). Restricted (VPN) accounts are rejected. Rate limited. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `202` Deployment accepted; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, server permission, or restricted account; `404` Not found: Server not found; `409` Conflict: Server unavailable; `412` Integration required: No repository linked; `429` Rate limited; `502` Upstream error: Node could not start the deployment ### GET /servers/{server_id}/git/deployments — List deployment history Returns paginated deployment records for the server (empty when the server has never deployed). Use `limit` (default 20, max 100) and `offset` for pagination. **Access** API scope: `servers:git:read` — Read linked repository status, branches, commits, file trees, and deployment history. Server access: owner, or server permission `git.read`. Parameters: - `server_id` (path, required): Falix server id - `limit` (query): Max results (default 20, max 100) - `offset` (query): Pagination offset (default 0) Responses: `200` Deployment list; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Database service unavailable ### PUT /servers/{server_id}/git/trigger-schedules — Trigger deploy-linked schedules Queues all active schedules with `trigger_type = git_push` for the server, as run automatically after a successful deployment. Schedules that fail to queue are skipped. Does not require a linked repository. **Access** API scope: `servers:git:write` — Link and unlink repositories, edit git settings, and manage deploy-triggered schedules. Server access: owner, or server permission `git.update`. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Triggered schedules; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `429` Rate limited; `503` Service unavailable: Database service unavailable ## Monitor ### GET /servers/{server_id}/monitor/crashes — Get a server's crash history Lists recorded crashes over the window (exit code, previous state, uptime, memory usage, OOM/restart flags). Supply `crash_time` (a timestamp from a listed crash) to fetch the console output captured around that crash instead. **Access** API scope: `servers:monitor:read` — Read health scores, resource monitoring data, crash history, and player-activity analytics. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time window: 15m, 1h, 6h, 24h (default), 3d, 7d, 30d - `crash_time` (query): Crash timestamp — returns console logs captured around that crash - `limit` (query): Max crashes to return (default 25, maximum 100). Ignored with crash_time. - `offset` (query): Crashes to skip (default 0). Ignored with crash_time. Responses: `200` Crash report or console logs; `400` Bad request: Invalid time range or query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Monitoring service unavailable ### GET /servers/{server_id}/monitor/data — Get a server's monitoring metrics Returns time-series resource metrics for the window (`view=metrics`, the default), long-term uptime statistics (`view=uptime_stats`), or predictive resource alerts (`view=predictive_alerts`). **Access** API scope: `servers:monitor:read` — Read health scores, resource monitoring data, crash history, and player-activity analytics. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time window: 15m, 1h, 6h, 24h (default), 3d, 7d, 30d - `view` (query): Dataset: metrics (default), uptime_stats, predictive_alerts Responses: `200` Monitoring metrics; `400` Bad request: Invalid time range or view; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Monitoring service unavailable ### GET /servers/{server_id}/monitor/health-score — Get a server's health score Computes a weighted 0–100 health score from CPU, memory, crash, uptime, and player-retention signals over the requested window, with a letter grade and a week-over-week trend. **Access** API scope: `servers:monitor:read` — Read health scores, resource monitoring data, crash history, and player-activity analytics. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time window: 15m, 1h, 6h, 24h (default), 3d, 7d, 30d Responses: `200` Health score; `400` Bad request: Invalid time range; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Monitoring service unavailable ### GET /servers/{server_id}/monitor/health-status — Get a server's health status Proxies the node's per-server health check. Returns `enabled: false` when the node is unreachable rather than an error. Internal node details (daemon version, physical-node uptime, connection errors) are omitted. **Access** API scope: `servers:monitor:read` — Read health scores, resource monitoring data, crash history, and player-activity analytics. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Health status; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited ### GET /servers/{server_id}/monitor/player-activity — Get a server's player-activity analytics Returns player-activity analytics for the requested `view`: `overview` (default), `timeline`, `events`, `peak_hours`, `players`, `heatmap`, `player_search` (requires `player`), `retention_funnel`, or `all`. **Access** API scope: `servers:monitor:read` — Read health scores, resource monitoring data, crash history, and player-activity analytics. Server access: owner, or server permission `control.console`. Parameters: - `server_id` (path, required): Falix server id - `range` (query): Time window: 15m, 1h, 6h, 24h (default), 3d, 7d, 30d - `view` (query): Analytics view: overview (default), timeline, events, peak_hours, players, heatmap, player_search, retention_funnel, all - `limit` (query): Row cap for the events and players views (10–100) - `player` (query): Player name to look up (required for player_search) Responses: `200` Player-activity analytics; `400` Bad request: Invalid view, time range, or player name; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Monitoring service unavailable ## Logs ### POST /servers/{server_id}/logs/ai-analyze — AI-analyze server logs Runs the enhanced (regex-based) analyzer over posted log text (up to 5 MB). No external model is invoked. Idempotent retries are supported for the full request size. **Access** API scope: `servers:logs:read`. Server access: owner, or server permission `file.read-content`. Regex-based enhanced analysis (no external model). Log content is posted in the request body (up to 5 MB), with idempotent retries supported. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Enhanced analysis result; `400` Bad request: Content too large; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Body exceeded the size limit; `429` Rate limited ### POST /servers/{server_id}/logs/analyze — Analyze server logs Runs pattern-based detection over posted log text (up to 5 MB). Idempotent retries are supported for the full request size. **Access** API scope: `servers:logs:read`. Server access: owner, or server permission `file.read-content`. Log content is posted in the request body (up to 5 MB), with idempotent retries supported. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Analysis result; `400` Bad request: Content too large; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Body exceeded the size limit; `429` Rate limited ### POST /servers/{server_id}/logs/patterns — List log analysis patterns Returns the catalog of known issue-detection patterns the analyzer uses, including the regex, severity, description, and category for each. **Access** API scope: `servers:logs:read`. Requires server access (owner or any subuser) but no specific server permission — it returns a static catalog and exposes no server data. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Pattern catalog; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server access; `404` Not found: Server not found; `429` Rate limited ### POST /servers/{server_id}/logs/share — Share a log snippet Persists a log snippet and returns a public /shared-logs link. Redacts all categories (IPs, auth, UUIDs, emails, coords, paths) by default; opt out per category. Idempotent retries are supported for the full request size. **Access** API scope: `servers:logs:write`. Server access: owner, or server permission `file.read-content`. Creates a public, no-auth `/shared-logs` link (expiry 1–30 days). Redaction defaults ON for every category (IPs, auth, UUIDs, emails, coords, paths) — opt out per category. Content is posted in the request body (up to 10 MB), with idempotent retries supported. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Shared log created; `400` Bad request: Empty or oversized content; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or server permission; `404` Not found: Server not found; `409` Conflict: Server unavailable; `413` Payload too large: Body exceeded the size limit; `429` Rate limited; `503` Service unavailable: Log sharing service unavailable ## Billing ### GET /account/billing — Retrieve the billing overview Returns the account's subscription summary, credit and outstanding balances, and per-server billing rows, computed with the same engine as the dashboard. Read-only: purchases, renewals, and payment methods are managed in the dashboard. **Access** API scope: `account:billing:read` — Read the subscription overview, balances, billing documents, and resource pricing. Never exposes payment methods or payment links.. Responses: `200` Billing overview; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Billing service unavailable ### GET /account/billing/balance — Retrieve the billing balance Returns the account's credit, prepaid, and outstanding balances in one lightweight object. An account with no subscription returns zeros with the default currency. **Access** API scope: `account:billing:read` — Read the subscription overview, balances, billing documents, and resource pricing. Never exposes payment methods or payment links.. Responses: `200` Billing balance; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Billing service unavailable ### GET /account/billing/documents — List billing documents Returns the account's invoices and credit notes (including purchased gift cards), newest first. Document PDFs are available from the dashboard under Billing → Invoices; the API returns metadata only. **Access** API scope: `account:billing:read` — Read the subscription overview, balances, billing documents, and resource pricing. Never exposes payment methods or payment links.. Parameters: - `limit` (query): Maximum documents to return (1-100). Defaults to 25. - `offset` (query): Number of documents to skip. Defaults to 0. Responses: `200` Billing documents, newest first; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Billing service unavailable ### GET /account/billing/pricing — Quote resource pricing Prices a RAM/CPU configuration with VAT and billing-cycle options, using the same engine as the dashboard. When the account already has open paid servers, totals are prorated onto the current billing period, exactly as a dashboard purchase would be. **Access** API scope: `account:billing:read` — Read the subscription overview, balances, billing documents, and resource pricing. Never exposes payment methods or payment links.. Parameters: - `ram_mb` (query, required): RAM to quote, in megabytes (512-32768). - `cpu_cores` (query, required): CPU cores to quote (1-8). - `currency` (query): Currency to quote in: `USD`, `EUR`, or `GBP`. Defaults to `USD`. - `country_code` (query): Country code for VAT (ISO 3166-1 alpha-2). Defaults to the account's saved tax country, then `US`. - `vat_country` (query): Business country for EU reverse-charge checks. When omitted, the account's saved VAT exemption applies. Responses: `200` Pricing quote; `400` Bad request: Invalid parameters; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Billing service unavailable ### GET /account/billing/pricing/catalog — Retrieve the pricing catalog Returns per-currency pricing rates and resource limits, the valid billing cycles, and the selectable provisioning locations — everything needed to build a valid pricing quote or server-creation request. Unlike the quote endpoint, this does not price a specific configuration or apply VAT; it is a static reference of the current rate card. **Access** API scope: `account:billing:read` — Read the subscription overview, balances, billing documents, and resource pricing. Never exposes payment methods or payment links.. Parameters: - `currency` (query): Restrict the catalog to a single currency: `USD`, `EUR`, or `GBP`. When omitted, all supported currencies are returned. Responses: `200` Pricing catalog; `400` Bad request: Invalid parameters; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Billing service unavailable ### POST /account/billing/top-up — Add prepaid credits Starts a hosted checkout that adds prepaid credits to the account. Returns a `checkout_url`; the credits are added automatically once the payment clears. Mirrors the dashboard add-credits flow exactly — the same pending record and checkout metadata — so the billing webhook fulfills API-started and dashboard-started top-ups identically. **Access** Initiates a real payment: returns a hosted checkout URL and adds credits once paid. Parameters: - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Checkout session created; `400` Bad request: Invalid amount, currency, or no subscription; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope; `429` Rate limited; `503` Service unavailable: Billing service unavailable ## Support Tickets ### GET /account/tickets — List support tickets Returns the support tickets visible to the account — those you own, are a participant on, or can see through a `support.view` permission on an attached server — newest activity first. List rows omit the message thread. **Access** Ticket access: owner, participant, or a subuser with the `support.view` server permission on an attached server. Parameters: - `limit` (query): Maximum number of tickets to return. Defaults to `25`; maximum `100`. - `offset` (query): Number of tickets to skip. Defaults to `0`. - `status` (query): Status filter: `all` (default), `active` (any non-closed), `open`, `answered`, `pending`, or `closed`. - `search` (query): Free-text search over the ticket subject, or an exact ticket id. Responses: `200` Support tickets; `400` Bad request: Invalid query parameter; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or support access is locked; `429` Rate limited; `503` Service unavailable: Support service unavailable ### POST /account/tickets — Open a support ticket Opens a new support ticket with an opening message. Requires support access to be unlocked for the account (a premium plan, an active access grant, or a prior purchase attempt), exactly like the dashboard. The returned object does not embed the thread — retrieve the ticket to read it. **Access** Account-level. Requires support access to be unlocked for the account (premium plan, an active access grant, or a prior purchase attempt), matching the dashboard. Parameters: - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Ticket opened; `400` Bad request: Invalid category, subject, description, or servers; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, or blacklisted; `429` Rate limited or open-ticket limit reached; `503` Service unavailable: Support service unavailable ### GET /account/tickets/{ticket_id} — Retrieve a support ticket Returns a support ticket and its full message thread (oldest first). Internal staff notes are never included. **Access** Ticket access: owner, participant, or a subuser with the `support.view` server permission on an attached server. Parameters: - `ticket_id` (path, required): Support ticket id Responses: `200` Support ticket with thread; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, or no ticket access; `404` Not found: Ticket not found; `429` Rate limited; `503` Service unavailable: Support service unavailable ### PATCH /account/tickets/{ticket_id} — Rename a support ticket Changes a ticket's subject. Requires manage access to the ticket (the owner or a participant granted `manage`). A system message records the change. **Access** Ticket access: the ticket owner (or a participant granted manage permission). Parameters: - `ticket_id` (path, required): Support ticket id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Ticket renamed; `400` Bad request: Invalid subject; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, or no manage access; `404` Not found: Ticket not found; `429` Rate limited; `503` Service unavailable: Support service unavailable ### POST /account/tickets/{ticket_id}/close — Close a support ticket Closes an open ticket. Requires manage access to the ticket (the owner or a participant granted `manage`). A system message records the change. **Access** Ticket access: the ticket owner (or a participant granted manage permission). Parameters: - `ticket_id` (path, required): Support ticket id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Ticket closed; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, or no manage access; `404` Not found: Ticket not found; `409` Conflict: Ticket is already closed; `429` Rate limited; `503` Service unavailable: Support service unavailable ### GET /account/tickets/{ticket_id}/participants — List support ticket participants Returns the ticket owner and any invited participants, each with their ticket permissions. Requires read access to the ticket. Profiles are sanitized to id, username, and avatar. **Access** Ticket access: owner, participant, or a subuser with the `support.view` server permission on an attached server. Parameters: - `ticket_id` (path, required): Support ticket id Responses: `200` Ticket participants; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, or no ticket access; `404` Not found: Ticket not found; `429` Rate limited; `503` Service unavailable: Support service unavailable ### POST /account/tickets/{ticket_id}/reopen — Reopen a support ticket Reopens a closed ticket. Requires manage access to the ticket (the owner or a participant granted `manage`). A system message records the change. **Access** Ticket access: the ticket owner (or a participant granted manage permission). Parameters: - `ticket_id` (path, required): Support ticket id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Ticket reopened; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, or no manage access; `404` Not found: Ticket not found; `409` Conflict: Ticket is not closed; `429` Rate limited; `503` Service unavailable: Support service unavailable ### POST /account/tickets/{ticket_id}/replies — Reply to a support ticket Posts a reply to a ticket. Replies to a closed ticket are rejected. A user reply moves an `answered`, `resolved`, or `pending` ticket back to `open`. **Access** Ticket access: owner, a participant granted the reply (write) permission, or a subuser with the `support.reply` server permission on an attached server. Parameters: - `ticket_id` (path, required): Support ticket id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Reply posted; `400` Bad request: Invalid message; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope, support access locked, no ticket access, or blacklisted; `404` Not found: Ticket not found; `409` Conflict: Ticket is closed; `429` Rate limited; `503` Service unavailable: Support service unavailable ## Support Access ### GET /servers/{server_id}/support-access — Retrieve the support-access grant Returns whether Falix staff currently hold time-boxed access to the server, and when that access expires. Owner only. **Access** Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id Responses: `200` Current support-access grant state; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Support-access service unavailable ### POST /servers/{server_id}/support-access — Grant staff access to the server Grants Falix staff time-boxed access to this server, for example so support can investigate a ticket. The grant expires automatically after `duration_minutes`; granting again while a grant is active replaces its expiration. Owner only. **Access** API scope: `servers:support-access:write` — opens the server to Falix staff, never granted by the `servers:*` wildcard; grant it explicitly. Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `201` Staff access granted; `400` Bad request: Invalid duration; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or not the server owner; `404` Not found: Server not found; `429` Rate limited; `503` Service unavailable: Support-access service unavailable ### DELETE /servers/{server_id}/support-access — Revoke staff access to the server Revokes the active support-access grant immediately. Owner only. **Access** API scope: `servers:support-access:write` — never granted by the `servers:*` wildcard; grant it explicitly. Server access: the server owner only. Parameters: - `server_id` (path, required): Falix server id - `Idempotency-Key` (header): Unique key for replay-safe retries. Reuse the same key only for the same request. Responses: `200` Staff access revoked; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing scope or not the server owner; `404` Not found: Server or active grant not found; `429` Rate limited; `503` Service unavailable: Support-access service unavailable ## Utilities ### GET /minecraft/status — Query a Minecraft server's live status Pings any public Java (Server List Ping) or Bedrock (RakNet) server by address and returns its MOTD, version, player counts, latency, and edition-specific extras. Set `edition` to `java`, `bedrock`, or `auto` (the default tries both concurrently and prefers whichever answers). The target is resolved and vetted — private, loopback, link-local, and other reserved addresses are refused with `400 bad_request`. Results are cached briefly, and both a per-key and a per-IP rate limit apply. Unreachable servers return `200` with `online: false`, not an error. **Access** Account-level utility. Requires no server access, only the utility:mcquery scope. Parameters: - `host` (query, required): Hostname or IP address to query. - `port` (query): Explicit port. Defaults to 25565 (Java) / 19132 (Bedrock); when the Java port is defaulted, `_minecraft._tcp` SRV records are followed. - `edition` (query): `java`, `bedrock`, or `auto` (default: try both, prefer Java). Responses: `200` Query result — online or offline; `400` Bad request: Invalid host, port, or edition, or a reserved address; `401` Authentication: Invalid or missing API key; `403` Authorization: Missing the utility:mcquery scope; `429` Rate limited; `503` Service unavailable: Query service unavailable