Octyne provides a REST API for interacting with the server (listening on port 42069 by default, but configurable). This API is used by the Ecthelion web interface and can be used by other applications to interact with Octyne.
Octyne v1.2+ provides a Unix socket API on Windows 10+ and Unix-like systems which is located by default at TEMPDIR/octyne.sock.PORT
, where TEMPDIR
is retrieved from https://pkg.go.dev/os#TempDir and PORT
is the port specified in the config (the default is 42069). If using an older version of Windows, the Unix socket API will be unavailable.
This API is identical to the REST API in usage, with the same endpoints/params/etc. You can send HTTP requests to this API without requiring token authentication, only necessary system user/group privileges, which is useful for local actions performed by applications like octynectl. Actions performed through the Unix socket API are logged as being performed by the @local
user.
Retrieve a token using the GET /login endpoint and store it safely. You can then pass this token to all subsequent requests to Octyne in the Authorization
header or as an X-Authentication
cookie (
If using the console API endpoint or the file download API endpoint, you can use the one-time ticket system to make the use of these endpoints in the browser JavaScript environment convenient. Use GET /ott (one-time ticket) to retrieve a ticket using your token (same as requests to any other endpoint), then pass it in the URL query parameters. A ticket is valid for 30 seconds, tied to your account and IP address, and can only be used once.
All endpoints may return an error. Errors are formatted in JSON in the following format: {"error": "error description here"}
.
Currently, possible errors are not documented. This will be done in the future. Contributions in this department are welcome!
- GET /
- GET /login
- GET /logout
- GET /ott (one-time ticket)
- GET /config
- PATCH /config
- GET /config/reload
- GET /accounts
- POST /accounts
- PATCH /accounts?username=username
- DELETE /accounts?username=username
- GET /servers
- GET /server/{id}
- POST /server/{id}
- WS /server/{id}/console?ticket=ticket
- GET /server/{id}/files?path=path
- PATCH /server/{id}/files
- GET /server/{id}/file?path=path&ticket=ticket
- POST /server/{id}/file?path=path
- POST /server/{id}/folder?path=path
- DELETE /server/{id}/file?path=path
- PATCH /server/{id}/file
- GET /server/{id}/compress?token=token
- POST /server/{id}/compress?path=path&compress=algorithm&archiveType=archiveType&basePath=path&async=boolean
- POST /server/{id}/decompress?path=path
Get the running version of Octyne. Added in v1.1.0.
Response:
HTTP 200 JSON body response containing the Octyne version e.g. {"version":"1.2.0"}
.
Hi, octyne is online and listening to this port successfully!
This is the only endpoint which doesn't require authentication, since it is the login endpoint to obtain authentication tokens from.
Request Query Parameters:
cookie
- Optional, defaults tofalse
. If set totrue
, the token will be returned in a cookie namedX-Authentication
instead, with a 3 month expiry,SameSite=Strict
andHttpOnly
(noSecure
, sinceSameSite=Strict
covers that when HTTPS is in use). Added in v1.1.0.
Request Headers:
Username
- The username of the account being logged into.Password
- The password of the account being logged into.
Response:
HTTP 200 JSON body response with the token is returned on success, e.g. {"token":"RCuRbzzSa51lNByCu+aeYXxoSeaO4HQgMJQ82gWqdSTPm7cHWCQxk7LoQEa8AIkiLBUQXCkkYF8gLHC3lOPfMVU4oU8rXGhQ1EB3VFP30VP2Dv7MG9clAsxuv2x+0jP5"}
.
If the cookie
query parameter is true
and Octyne v1.1+ is in use, then the body will be {"success":true}
instead, and the token will be contained in the X-Authentication
cookie in Set-Cookie
header (see cookie
's documentation for details).
Logout from Octyne. This invalidates your authentication token.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Provides you with a one-time ticket which can be used for authenticating with certain endpoints (see the Authentication section for more details).
Response:
HTTP 200 JSON body response with the ticket e.g. {"ticket":"UTGA3Q=="}
is returned on success. This ticket is tied to your account, IP address, can be used for one request only, and will expire in 30 seconds.
Get Octyne's configuration file contents. Added in v1.1.0.
Response:
HTTP 200 response with the configuration file contents in the body. The configuration file format is documented in the README.
Modify Octyne's configuration. Added in v1.1.0.
Request Body:
New configuration file contents in the body. The configuration file format is documented in the README and is formatted with HuJSON.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
This endpoint tells Octyne to reload config.json
from disk. Added in v1.1.0.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Get a list of all accounts. Added in v1.1.0.
Response:
HTTP 200 JSON body response with an array of all usernames e.g. ["user1", "user2"]
is returned on success.
This endpoint can be used to create a new account. Added in v1.1.0.
Request Body:
A JSON body containing the username and password of the account to be created, e.g. {"username":"user1", "password":"password1"}
(don't use these usernames or passwords in production lol).
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
This endpoint can be used to change the username/password of an account. Added in v1.1.0.
Request Query Parameters:
username
- The username of the account to be changed. When missing, the username in the body is used instead. You must use this parameter if you want to rename an account. Added in v1.2.0.
Request Body:
A JSON body containing the new username and password of the account, e.g. {"username":"user1", "password":"password1"}
(don't use these usernames or passwords in production lol).
username
query parameter to specify the old username. However, the query parameter is only available since v1.2+! On older versions, you cannot rename accounts, and the query parameter will not be used for changing passwords either! If you want to avoid issues, don't allow the user to change both the username and password at the same time, or you may end up changing the password of a different user instead of renaming the current one! On older versions, attempting to change only the username will give you a "Username or password not provided!" error. Alternatively, you can implement a version check with the GET /
endpoint.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Delete an account. Added in v1.1.0.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Get a list of all servers along with basic information about them.
Request Query Parameters:
extrainfo
- Optional, defaults tofalse
. If set totrue
, the response will include extra information about the server, currently whether or not the server is marked for deletion (toDelete
). Added in v1.2.0.
Response:
HTTP 200 JSON body response with the status of all servers e.g. {"servers":{"app1":0, "app1": 1}}
is returned on success.
0
means the returned server is not running.1
means the returned server is currently running.2
means the returned server has crashed and is not currently running.
If the query parameter extrainfo
is true
, then the response will include extra information about the server, like so:
{
"servers": {
"app1": { "status": 0, "toDelete": true },
"app2": { "status": 1, "toDelete": false }
}
}
Get info about a specific server/app.
Response:
HTTP 200 JSON body response with information about the app.
status
- The status of the app,0
for not running,1
for running,2
for crashed.uptime
- The uptime of the app in nanoseconds.cpuUsage
- The CPU usage of the app in percent.memoryUsage
- The memory usage of the app in bytes.totalMemory
- The total memory available to the app in byte.toDelete
- Whether or not the app is marked for deletion.
e.g.
{
"status": 0,
"uptime": 60000000000,
"cpuUsage": 70,
"memoryUsage": 1073741824,
"totalMemory": 8589934592,
"toDelete": false
}
Start, stop or kill a server/app.
Request Body:
Either of the following words in the body:
START
- Start the server.STOP
- Kill the server with SIGKILL.⚠️ Warning: Deprecated in v1.1 in favour ofKILL
andTERM
.KILL
- Kill the server with SIGKILL. Added in v1.1.TERM
- Gracefully stop the server with SIGTERM. Added in v1.1.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Connect to the console of a server/app to receive its input/output. This endpoint is a WebSocket endpoint.
Request Query Parameters:
ticket
- Optional. For browsers and other such environments where you cannot set custom headers, you can use one-time tickets as described in the Authentication section instead of setting theAuthorization
header.
WebSocket Protocols:
⚠️ None provided: If no protocol is specified, the old protocol is used by default. This only exists for backwards compatibility! Avoid using this protocol if possible.console-v2
: This is the recommended protocol to use, since it has a proper extensible format and supports keep alives. Added in v1.1.0.
Info: All messages with either protocol are encoded as WebSocket text messages.
Default protocol:
console-v2
protocol instead, as this protocol will likely be removed with Octyne v2+.
After establishing a connection, you receive all the output logs from the app so far, and you continue to receive logs line-by-line. You can send input to the app by sending the input string over the WebSocket connection.
console-v2 protocol:
In this protocol, all messages are encoded in JSON strings in the following format:
{
"type": "type",
// ... other fields
}
The client may receive messages of the following types:
settings
- This is sent upon initial connection, and is currently unused and has no fields.error
- This is sent when an error occurs, and has the following fields:message
- The error message.
output
- This contains output from the app, sent in sequential order, and has the following fields:data
- The output received from the app. This can be appended to the previous output with a newline, and anoutput
message may contain multiple lines joined with\n
as well.
pong
- This is sent in response to aping
message, and has the following fields:id
- The ID from the client'sping
message.
The client may send messages of the following types:
ping
- This is sent to check if the connection is still alive, and has the following fields:id
- A unique ID for this ping message. The server will respond with apong
message with the same ID.
input
- This is sent to send input to the app, and has the following fields:data
- The input to send to the app.
A client will receive the output from the app so far upon initial connection, will continue to receive output line-by-line, and can send input to the app, just like the older, deprecated v1 protocol. Clients should send a ping
message every few seconds to keep the connection alive, as Octyne enforces a 30 second timeout.
Get a list of all files in a folder in the working directory of the app.
Request Query Parameters:
path
- The path of the folder to list contents of. This is relative to the server's root directory.
Response:
HTTP 200 JSON body response with an array of all files in the folder.
Properties include:
folder
- Whether or not the file is a folder.name
- The name of the file.size
- The size of the file in bytes.lastModified
- The last modified time of the file in seconds since the Unix epoch.mimeType
- The MIME type of the file.
Example response:
{
"contents": [
{
"folder": false,
"name": "config.json",
"size": 1284,
"lastModified": 1600000000,
"mimeType": "application/json"
}
]
}
A transactional file API for performing multiple file operations in a single request. Added in v1.3.
GET
request was made). An efficient way to check if the API is available is by passing ?path=..
with the request, which will error on older versions.
Each operation is performed in order, and if any operation fails, the entire transaction is rolled back.
Note:
- Individual operations can depend upon each other, but they should not! As of v1.3, this could cause a triggered rollback to mangle the filesystem state if any link in a dependency chain fails to revert. This API currently does not guarantee atomicity.
- For
mv
orcp
operations, the destination must not already exist unless overwriting one file with another.
Request Body:
{
"operations": [
{ "operation": "mv", "src": "/config.json", "dest": "/config.json.old" },
{ "operation": "cp", "src": "/config.json.old", "dest": "/config.json" },
{ "operation": "rm", "path": "/config.json" }
]
}
Response:
HTTP 200 JSON body response {"success":true}
is returned on success. On failure, the response will be in the following format:
{
"success": false,
"errors": [
{ "index": 0, "message": "error message here" },
{ "index": 2, "message": "error message here" }
]
}
If the status code is 400 Bad Request, the errors indicate validation errors in your request. Else, the HTTP status code and first error in the array belong to the first operation that failed in the transaction. If operations in the transaction rollback attempt fail, subsequent errors will be present and 500 Internal Server Error will always be returned. In such cases, something catastrophic has happened and manual intervention from the user is advised.
Download a file from the working directory of the app.
Request Query Parameters:
path
- The path of the file to download. This is relative to the server's root directory.ticket
- Optional. For browsers and other such environments where you cannot set custom headers, you can use one-time tickets as described in the Authentication section instead of setting theAuthorization
header.
Response:
HTTP 200 response with the file contents in the body is returned on success.
Response Headers:
These are helpful for apps and allow browsers to download files directly from this endpoint as well (provided you use a one-time ticket/pass Authorization
header somehow).
Content-Disposition
- The filename of the file being downloaded e.g.Content-Disposition: attachment; filename=file.txt
.Content-Type
- The MIME type of the file being downloaded.Content-Length
- The length of the file being downloaded.
Upload a file to the working directory of the app.
Request Query Parameters:
path
- The path to the folder where the file should be uploaded. This is relative to the server's root directory.
Request Body:
The body should be multipart form data, where the contents of the file you want to upload should be in a key named upload
, and the filename in its metadata should correctly reflect the filename you want once it's uploaded. The upload limit is 5 GB since v1.1+ (was previously 100 MB in v1.0).
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Create a folder in the working directory of the app.
Request Query Parameters:
path
- The path where the folder should be created. This is relative to the server's root directory.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Delete a file or folder in the working directory of the app.
Request Query Parameters:
path
- The path of the file or folder to delete. This is relative to the server's root directory.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Move or copy a file or folder in the working directory of the app.
Request Body:
-
Old format (
⚠️ Warning: deprecated):mv
orcp
, the old path of the file/folder, and the new path, joined together by new lines, e.g.mv /config.json /config.json.old
-
New format (added in v1.1+): Similar in working to the old format, but uses JSON to encode the body, e.g.
{ "operation": "mv", "src": "/config.json", "dest": "/config.json.old" }
Get the progress of an async compression request. Added in v1.2+.
Request Query Parameters:
token
- The token returned by POST /server/{id}/compress?path=path&compress=algorithm&archiveType=archiveType&basePath=path&async=boolean corresponding to your compression request.
Response:
HTTP 200 JSON body response {"finished":true}
is returned on success. If the compression request is still in progress, the body will be {"finished":false}
, and HTTP 500 errors will be returned if the compression request failed.
POST /server/{id}/compress?path=path&compress=algorithm&archiveType=archiveType&basePath=path&async=boolean
Compress files/folders in the working directory of the app into a ZIP or TAR archive. Support for tar(.gz/xz/zst)
archives was added in v1.2+.
POST /server/{id}/compress/v2
API is available as well, which is identical to this, but guaranteed to support tar
archives, the basePath
and async
query parameters. The v2 endpoint can be used by API clients to ensure archives aren't accidentally created as ZIP files on older Octyne versions.
Request Query Parameters:
path
- The location to create the archive at. This is relative to the server's root directory.basePath
- Optional, default is/
. The location containing all files in the request body. This is used as the archive's top-level directory, all file paths in the request body are calculated relative tobasePath
. Added in v1.2+.archiveType
- Optional, default iszip
. This specifies the archive type to use, currently,zip
andtar
are supported. Added in v1.2+.compress
- Optional, default istrue
, possible values aretrue
/false
, andgzip
/zstd
/xz
fortar
archives. This specifies whether or not to compress files/folders in the archive.true
corresponds to the default DEFLATE algorithm forzip
, and GZIP fortar
.⚠️ Warning: This was broken in v1.0 (it accidentally used a header instead of query parameter), this was fixed in v1.1+.async
- Optional, default isfalse
. Iftrue
, the endpoint will return a token immediately instead of waiting for the archive to compress. This token can be used against GET /server/{id}/compress?token=token to get the status of the compression request. The token expires 10 seconds after the compression request has been serviced. Added in v1.2+.
Request Body:
A JSON body containing an array of paths to compress (relative to the server's root directory), e.g. ["/config.json", "/logs"]
.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
Decompress a ZIP or TAR archive in the working directory of the app.
The full list of supported archive formats is:
.zip
.tar(.gz/bz2/bz/zst/xz)
and their respective short formstgz/txz/tbz/tbz2/tzst
, support for these was added in v1.2+.
Request Query Parameters:
path
- The path of the archive to decompress. This is relative to the server's root directory.
Request Body:
A string containing the path to decompress the archive to (relative to the server's root directory). A folder will be created at this path, to which the contents of the archive will be extracted.
Response:
HTTP 200 JSON body response {"success":true}
is returned on success.
tar
on Octyne v1.1 and older: Check if the error is An error occurred when decompressing ZIP file!
v1.2+ says archive
instead of ZIP file
and explicitly blocks unsupported archive types. This can help you inform the user if their Octyne installation is out of date, since decompressing these archives will fail on older versions.