openfsd REST & frontend interface
Overview
This API provides programmatic access to manage users, configurations, authentication, and FSD connections. All API endpoints are versioned under /api/v1 and use JSON for request and response bodies unless otherwise specified. Authentication is primarily handled via JWT bearer tokens.
Authentication
Most endpoints require a valid JWT access token included in the Authorization header as a Bearer token:
Authorization: Bearer <access_token>
- API tokens can be created via
/api/v1/config/createtokenwith a custom expiry date. See the Server Configuration menu in the frontend UI to generate one.
Network Ratings
The API enforces role-based access control using NetworkRating values defined in the fsd package. Key thresholds:
- Supervisor (11): Can manage users (create, update, retrieve) and kick active connections.
- Administrator (12): Can manage server configuration, reset JWT secret keys, and create API tokens.
Error Handling
All API responses follow a standard APIV1Response structure:
{
"version": "v1",
"err": string | null,
"data": object | null
}
- err: Contains an error message if the request fails; otherwise, null.
- data: Contains the response data if relevant.
Common HTTP status codes:
- 200 OK: Request succeeded.
- 201 Created: Resource created successfully.
- 400 Bad Request: Invalid request body or parameters.
- 401 Unauthorized: Invalid or missing credentials.
- 403 Forbidden: Insufficient permissions.
- 404 Not Found: Resource not found.
- 500 Internal Server Error: Server-side error.
Endpoints
Authentication
POST /api/v1/auth/login
Obtain access and refresh tokens using FSD login credentials. NOTE: Do not use this endpoint for programmatic access from an external application. Instead, generate an API token using the Configure Server menu via the frontend.
Request Body:
{
"cid": integer, // User certificate ID (min: 1)
"password": string, // User password
"remember_me": boolean // Extend refresh token validity to 30 days if true
}
Response (200 OK):
{
"version": "v1",
"err": null,
"data": {
"access_token": string, // JWT access token
"refresh_token": string // JWT refresh token
}
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid CID or password.
- 500 Internal Server Error: Server-side error generating tokens.
Permissions: None (public endpoint).
POST /api/v1/auth/refresh
Refresh an access token using a refresh token. NOTE: Do not use this endpoint for programmatic access from an external application. Instead, generate an API token using the Configure Server menu via the frontend.
Request Body:
{
"refresh_token": string // JWT refresh token
}
Response (200 OK):
{
"version": "v1",
"err": null,
"data": {
"access_token": string // New JWT access token
}
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid or non-refresh token.
- 500 Internal Server Error: Server-side error retrieving JWT secret or generating token.
Permissions: None (public endpoint).
POST /api/v1/fsd-jwt
Obtain an FSD JWT token (see authentication-tokens in the FSD docs). This call matches the functionality of the VATSIM /api/fsd-jwt endpoint.
Request Body (form-encoded or JSON):
{
"cid": string, // User certificate ID
"password": string // User password
}
Response (200 OK):
{
"success": true,
"token": string // FSD JWT token
}
Errors:
- 400 Bad Request: Invalid CID format.
- 401 Unauthorized: Invalid CID or password.
- 403 Forbidden: User certificate is suspended or inactive.
- 500 Internal Server Error: Server-side error retrieving JWT secret or generating token.
Permissions: None (public endpoint).
User Management
POST /api/v1/user/load
Retrieve user information by CID.
Request Body:
{
"cid": integer // User certificate ID (min: 1)
}
Response (200 OK):
{
"version": "v1",
"err": null,
"data": {
"cid": integer,
"first_name": string,
"last_name": string,
"network_rating": integer // -1 to 12
}
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (non-self CID requires Supervisor rating).
- 404 Not Found: User not found.
- 500 Internal Server Error: Database error.
Permissions: Requires valid JWT access token. Users can retrieve their own info; Supervisor rating (11) required for other users' info.
PATCH /api/v1/user/update
Update user information by CID. The CID itself is immutable and is only provided as reference of the user to update.
Request Body:
{
"cid": integer, // User certificate ID (min: 1)
"password": string|null, // New password
"first_name": string|null, // New first name
"last_name": string|null, // New last name
"network_rating": integer|null // New network rating (-1 to 12)
}
Response (200 OK):
{
"version": "v1",
"err": null,
"data": {
"cid": integer,
"first_name": string,
"last_name": string,
"network_rating": integer
}
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Supervisor rating required; cannot update users with higher rating).
- 404 Not Found: User not found.
- 500 Internal Server Error: Database error.
Permissions: Requires valid JWT access token and Supervisor rating (11). Cannot update users with a higher network rating.
POST /api/v1/user/create
Create a new user.
Request Body:
{
"password": string, // Password (min: 8 characters)
"first_name": string|null, // First name
"last_name": string|null, // Last name
"network_rating": integer // Network rating (-1 to 12)
}
Response (201 Created):
{
"version": "v1",
"err": null,
"data": {
"cid": integer, // Assigned certificate ID
"first_name": string|null,
"last_name": string|null,
"network_rating": integer
}
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Supervisor rating required; cannot create users with higher rating).
- 500 Internal Server Error: Database error.
Permissions: Requires valid JWT access token and Supervisor rating (11). Created user's network rating cannot exceed the requester's.
Configuration Management
GET /api/v1/config/load
Retrieve server configuration key-value pairs.
Request: No body required.
Response (200 OK):
{
"version": "v1",
"err": null,
"data": {
"key_value_pairs": [
{
"key": string, // e.g., "welcome_message"
"value": string
}
]
}
}
Supported Keys:
WELCOME_MESSAGEFSD_SERVER_HOSTNAMEFSD_SERVER_IDENTFSD_SERVER_LOCATIONAPI_SERVER_BASE_URL
Errors:
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Administrator rating required).
- 500 Internal Server Error: Database error.
Permissions: Requires valid JWT access token and Administrator rating (12).
POST /api/v1/config/update
Update server configuration key-value pairs.
Request Body:
{
"key_value_pairs": [
{
"key": string, // Configuration key
"value": string // New value
}
]
}
Response (200 OK):
{
"version": "v1",
"err": null,
"data": null
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Administrator rating required).
- 500 Internal Server Error: Database error.
Permissions: Requires valid JWT access token and Administrator rating (12).
POST /api/v1/config/resetsecretkey
Reset the JWT secret key used for signing tokens. Upon successfully calling this endpoint, this effectively invalidates all previously-administered authentication tokens. All users using the frontend will be logged out. All previously-generated API tokens will be invalidated.
Request: No body required.
Response (200 OK):
{
"version": "v1",
"err": null,
"data": null
}
Errors:
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Administrator rating required).
- 500 Internal Server Error: Error generating or storing new secret key.
Permissions: Requires valid JWT access token and Administrator rating (12).
POST /api/v1/config/createtoken
Create a new API access token with a specified expiry.
Request Body:
{
"expiry_date_time": string // ISO 8601 format (e.g., "2025-12-31T23:59:59.000Z")
}
Response (201 Created):
{
"version": "v1",
"err": null,
"data": {
"token": string // JWT access token
}
}
Errors:
- 400 Bad Request: Invalid JSON body or expiry date in the past.
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Administrator rating required).
- 500 Internal Server Error: Error generating or signing token.
Permissions: Requires valid JWT access token and Administrator rating (12).
FSD Connection Management
POST /api/v1/fsdconn/kickuser
Kick an active user connection by callsign.
Request Body:
{
"callsign": string // User callsign
}
Response (200 OK):
{
"version": "v1",
"err": null,
"data": null
}
Errors:
- 400 Bad Request: Invalid JSON body.
- 401 Unauthorized: Invalid bearer token.
- 403 Forbidden: Insufficient permissions (Supervisor rating required).
- 404 Not Found: Callsign not found.
- 500 Internal Server Error: Error communicating with FSD HTTP service.
Permissions: Requires valid JWT access token and Supervisor rating (11).
Data Endpoints
GET /api/v1/data/status.txt
Retrieve server status in plain text format. Mimics the VATSIM status.txt format.
Request: No body required.
Response (200 OK):
- Content-Type:
text/plain - Body: Template-generated status text with carriage return newlines (
\r\n).
Errors:
- 500 Internal Server Error: Error retrieving base URL or generating template.
Permissions: None (public endpoint).
GET /api/v1/data/status.json
Retrieve server status in JSON format. Mimics the VATSIM status.json format.
Response (200 OK):
{
"data": {
"v3": [string], // URL to openfsd-data.json
"servers": [string], // URL to openfsd-servers.json
"servers_sweatbox": [string], // URL to sweatbox-servers.json
"servers_all": [string] // URL to all-servers.json
}
}
Errors:
- 500 Internal Server Error: Error retrieving base URL or marshaling JSON.
Permissions: None (public endpoint).
GET /api/v1/data/openfsd-servers.txt
Retrieve server list in plain text format. Mimics the VATSIM vatsim-servers.txt format.
Request: No body required.
Response (200 OK):
- Content-Type:
text/plain - Body: Template-generated server list with carriage return newlines (
\r\n).
Errors:
- 500 Internal Server Error: Error retrieving server info or generating template.
Permissions: None (public endpoint).
GET /api/v1/data/openfsd-servers.json
Retrieve server list in JSON format. Mimics the VATSIM vatsim-servers.json format.
Response (200 OK):
[
{
"ident": string,
"hostname_or_ip": string,
"location": string,
"name": string,
"clients_connection_allowed": integer,
"client_connections_allowed": boolean,
"is_sweatbox": boolean
}
]
Errors:
- 500 Internal Server Error: Error retrieving server info or marshaling JSON.
Permissions: None (public endpoint).
GET /api/v1/data/sweatbox-servers.json
Retrieve sweatbox server list in JSON format (same as openfsd-servers.json but with is_sweatbox: true).
Response: Same as /openfsd-servers.json.
Errors: Same as /openfsd-servers.json.
Permissions: None (public endpoint).
GET /api/v1/data/all-servers.json
Retrieve all servers in JSON format (same as openfsd-servers.json).
Response: Same as /openfsd-servers.json.
Errors: Same as /openfsd-servers.json.
Permissions: None (public endpoint).
GET /api/v1/data/openfsd-data.json
Retrieve cached datafeed of online pilots and ATC.
Response (200 OK):
{
"pilots": [
{
// fsd.OnlineUserPilot fields
}
],
"atc": [
{
// fsd.OnlineUserATC fields
}
]
}
Errors:
- 500 Internal Server Error: Datafeed cache not available.
Permissions: None (public endpoint).
Notes: Data is cached and updated every 15 seconds via an internal worker.