tgstation-server 6.5.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
API

OpenAPI Spec

TGS has a, from code, generated OpenAPI 3.0 specification. It is much more authorative than these documents.

The most up to date version should be found in the most recent appveyor build artifacts. It is also included in release artifacts.

You can use the API explorer SwaggerUI to interact with it: https://tgstation.github.io/tgs-api-doc-host/

Introduction

The TGS API is designed to be a fully realized RESTful service. Once hosted, follow the specified protocol for developing new clients or one off requests that provide full control over the server

Routes and their usages are defined as follows

[I (If Instance is required)] <Http Method> "<`Route`>" [Request Model] => <Response Model>

Official Libraries

The TGS API's canonical definitions are provided as a .NET Standard library in the form of a nuget package located here: https://www.nuget.org/packages/Tgstation.Server.Api

An all inclusive TAP interface for using the API is also provided in this package: https://www.nuget.org/packages/Tgstation.Server.Client

Last off, if anything in this API doesn't seem to hold true when tested against the server, please open an issue on the repository.

Interpreting C# Models

This document will reference the canonical C# models in the Tgstation.Server.Api.Models namespace. Note that these models are built to mirror the JSON requests and responses with a couple caveats.

  • The first letter of every field name will/must be lowercase in JSON models
  • Fields marked 'Required' should be ignored, this is a semantic for the backing SQL database
  • Id fields must be specified when making POST requests
  • All other fields are optional and may be absent from responses or requests unless otherwise specified
  • Request models can be found in Tgstation.Server.Api.Models.Request. Response models can be found in Tgstation.Server.Api.Models.Response.

Headers

TGS expects this set of headers. Failure to provide them will result in 400 error responses

  • User-Agent: The user agent product header value of the calling program
  • Api: Another product header value representing the version of the API to use. Currently this must be: Tgstation.Server.Api/4.0.0.0

For POST, PATCH, and PUT requests you must also include the content type. Currently only json is supported

  • Content-Type: application/json

For requests made to any Instance based API's a header with the Instance's ID must be provided

  • Instance: The ID of the instance being accessed

An Authentication header is also required. See Authentication

Response Codes

TGS will only every return the response codes listed here

  • 200: OK. The response body will contain a json model or array depending on the API called.
  • 201: Created. Returned when the request created an entity, 202 trumps this
  • 202: Accepted. Used when a response triggers a long running operation such as a Tgstation.Server.Api.Models.Job or server restart
  • 204: No Content. Identical to 200 with no response body.
  • 400: Bad Request. The response body will contain an Tgstation.Server.Api.Models.ErrorMessage model detailing the error
  • 401: Unauthorized. Invalid or expired credentials were provided. Check rights APIs for updates. See Authentication for details
  • 403: Forbidden. User tried to make a request they were not allowed to perform.
  • 404: Not found. A resource was requested that had never existed. In the case of retrieving a resource by ID, it could potentially exist in the future
  • 406: Not Acceptable. Consequence of failing to provide an Accept header
  • 408: Request Timeout. The client took to long to continue a request
  • 409: Conflict. Documented in the requests that use them
  • 410: Gone. Attempted to access/modify a resource that ideally should have been ready, but isn't or no longer is
  • 422: Unprocessable Entity: Used specifically when an operation that requires a server restart is unable to be performed due to the Tgstation.Server.Host.Watchdog not being present in the deployment. Should not happen with a proper server configuration. Response body contains an Tgstation.Server.Api.Models.ErrorMessage
  • 424: Failed Dependency: When a request that depends on an external API fails for a reason other than rate limiting. The response body will contain an Tgstation.Server.Api.Models.ErrorMessage model detailing the error.
  • 429: Rate limited. Used with operations that rely on GitHub.com. If a rate limit is hit for an operation this will be returned. Response will contain a Retry-After header with the amount of seconds to wait.
  • 500: Server error. Please report the request and response body to the code repository
  • 501: Not implemented. Functionality not available in the current server version
  • 503: Service unavailable. The server is either starting up or shutting down and isn't ready to respond to requests. You can try again soon and a response/lack thereof will indicate which of the two events it was

Server Information

The versions of the TGS host can be retireved with this request.

Note: This endpoint does not require authentication

GET "/" => Tgstation.Server.Api.Models.ServerInformation

The Version model fields are based on the C# one and looks like this:

{
"version": "<major>.<minor>.<patch>.<revision>"
}

Other fields may be present in the Version model but should be ignored. See a description of these version numbers here.

Authentication

Every request made to TGS requires authentication. It is provided in the form of the Authorization header.

The first request made to TGS must be to login the user

POST "/" => Tgstation.Server.Api.Models.Token

Headers:

  • Authorization:Basic <Base64 encoded credentials in the form username:password>

If the provided credentials are valid and your user account is enabled you will recieve a Tgstation.Server.Api.Models.Token object

{
"bearer": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwiZXhwIjoiMTUzMzIzNjk0MSIsIm5iZiI6IjE1MzMyMzYwNDEiLCJpc3MiOiJUZ3N0YXRpb24uU2VydmVyLkhvc3QiLCJhdWQiOiJUZ3N0YXRpb24uU2VydmVyLkFwaSJ9.QWFSWNi9mgol582zaK4MQ5XDK2gZF-Nx3z9_ToHjKW4"
}

If your account is disabled, you will receive a 403 response.

You may recognize the bearer value as a Json Web Token. This is a secure representation of your identity to the server. It expires after a set period of time or until your password changes. It must be present for requests made to all other APIs. To do so add the following header to your other requests

  • Authorization:Bearer <your bearer token>

Continue to use this token until you begin to receive 401 responses from the API. Then repeat the process to get a new one if your credentials are still valid

OAuth 2.0

TGS supports OAuth 2.0 with select providers for authentication.

The flow for this is as follows:

POST "/" => Tgstation.Server.Api.Models.Token

Headers:

  • Authorization:OAuth OAuth Authorization Response Code
  • OAuthProvider:<Provider Name>

You will be granted a bearer token as in basic auth. This will have an extended expiration to avoid repeating the entire process.

Supported Providers

Permissions

Almost all actions available require some level of user permissions. Which are divided into two categories:

  • General permissions apply to a user across the entire service
  • Instance permissions apply only when interacting with a specific instance

Permissions are represented a a 32 bit integer in the form of bitflags. The two endpoints for retrieving these permission are:

GET "/Users" => Tgstation.Server.Api.Models.User I GET "/InstanceUser" => Tgstation.Server.Api.Models.InstanceUser

See individual documentation of each permission enum for their usage

File Transfers

Certain responses inherit from Tgstation.Server.Api.Models.FileTicketResult. These are special in that, having that model's Tgstation.Server.Api.Models.FileTicketResult.FileTicket field populated indicates there is a pending file download or upload to take place. These are handled in the "/Transfer" endpoint.

To perform a file download make the following request:

GET "/Transfer?ticket=<@ref Tgstation.Server.Api.Models.FileTicketResult.FileTicket>" => application/octet-stream

To perform a file upload make the following request:

PUT "/Transfer?ticket=<@ref Tgstation.Server.Api.Models.FileTicketResult.FileTicket>" application/octet-stream => OK

File tickets are only valid for a short time after the initial request is made and should be dealt with immediately. Ensure that the file tickets are properly URL encoded.

User Management

TGS start with one user: "Admin". The password is "ISolemlySwearToDeleteTheDataDirectory"

There are two types of users that can be created: Database users and system users. Database users are your plain login/password style users. System users are based on either Windows or POSIX accounts depending on the host system. They cannot be created by TGS and have to be activated by adding them to the Database similarly to a normal user using the "SystemIdentifier" field which should generally be set to their username or DOMAIN\Username in an active directory environment. These act the same as regular users with the only exception being Static Files. See that section for details.

New users can be created with the following method.

PUT "/User" Tgstation.Server.Api.Models.UserUpdate => Tgstation.Server.Api.Models.User

To create a regular user, populate the name and password fields. To create a system user populate the SystemIdentifier field. Users rights and enabled status can also be specified in this call. To change them later use this API.

POST "/User" Tgstation.Server.Api.Models.UserUpdate => Tgstation.Server.Api.Models.User

Passowords for database users may be changed as well using this call. The capitalization of the display name of a user may also be changed

Instance User Management

Instance users must be created for a given instance before being manipulated. The creator of an instance starts with full permissions on it

I PUT "/InstanceUser" Tgstation.Server.Api.Models.InstanceUser => Tgstation.Server.Api.Models.InstanceUser

They can be updated with a similar POST

I POST "/InstanceUser" Tgstation.Server.Api.Models.InstanceUser => Tgstation.Server.Api.Models.InstanceUser

Unlike regular users, they can also be deleted, which prevents the user from discovering the instance

I DELETE "/InstanceUser/{UserId}" => OK

Users with the permission to modify Tgstation.Server.Api.Models.Instance objects can also gain user editing rights for any Instance. See api_instance

Server-wide Administrative Actions

You can retrieve server update information with this

GET "/Administration" => Tgstation.Server.Api.Models.Administration

If you want to perform a live update of the server use

POST "/Administration" Tgstation.Server.Api.Models.Administration => OK

With the Tgstation.Server.Api.Models.Administration.NewVersion field set

Any DreamDaemon servers running will persist while the server installs the new version from the official tgstation-server GitHub (If it exists)

If the server is otherwise acting funky and you wish to restart it, use this request:

DELETE "/Administration" => OK

Instances

Instances are DreamDaemon server configurations, they live in their own directory on the disk somewhere you specify. TGS starts with no default instance, to create one use this request:

PUT "/Instance" Tgstation.Server.Api.Models.Instance => Tgstation.Server.Api.Models.Instance

This normally returns 201 BUT, in the case of attaching an existing instance, 200 will instead be returned

The user that creates an instance will be given full Tgstation.Server.Api.Models.InstanceUser permission. The path must not exist at the time of creation. Support for attaching instances from backups is yet to come.

A specific Instance may be retrieved with:

GET "/Instances/{InstanceID}" => Tgstation.Server.Api.Models.Instance

Instances start offline, regardless of what was specified during the create request. An offline instance will return 403 for all requests made to it.

To online or change other instance variables use the following request. Note that using this request (even with an empty object) will automatically give you the Tgstation.Server.Api.Rights.InstanceUserRights.WriteUsers right for that instance if you don't have it

POST "/Instance" Tgstation.Server.Api.Models.Instance => Tgstation.Server.Api.Models.Instance

Note that onlining an offline instance will never automatically start DreamDaemon. That must be done as a seperate step.

Instances can be detached which will delete all meta knowledge of the instance (Compile metadata, job metadata, repository commit metadata, Test merge metadata, etc...) but leave the files intact. That can be done with this request:

DELETE "/Instance/{InstanceId}" => OK

Jobs

Some requests return Tgstation.Server.Api.Models.Job objects. These are long running tasks the server will perform asyncronously and can be polled for status.

Note that the job representing instance move operations must be queried and cancelled differently than others. See the documentation of Tgstation.Server.Api.Models.Instance.MoveJob for details

To list all jobs in an Instance use the following request

I GET "/Job/List" => Array of Tgstation.Server.Api.Models.Job

Note that the response for this request will only have the Tgstation.Server.Api.Models.Job.Id field populated

To get full details of active jobs use the following request:

I GET "/Job" => Array of Tgstation.Server.Api.Models.Job

To get full details of a specific job use the following request:

I GET "/Job/{JobId}" => Tgstation.Server.Api.Models.Job

To cancel a running job (If the job can be cancelled and you have sufficient rights) use the following request:

I DELETE "/Job/{JobId}" => OK

Chat Bots

Each chat bot is represented by a Tgstation.Server.Api.Models.ChatBot object

Chat bots can be created/updated/deleted with the following requests respectively

I PUT "/Chat" Tgstation.Server.Api.Models.ChatBot => Tgstation.Server.Api.Models.ChatBot I POST "/Chat" Tgstation.Server.Api.Models.ChatBot => Tgstation.Server.Api.Models.ChatBot I DELETE "/Chat/{ChatBotId}" => OK

The Tgstation.Server.Api.Models.Internal.ChatBot.ConnectionString must differ based on what kind of chat bot you wish to create. Each Tgstation.Server.Api.Models.ChatProvider has a Tgstation.Server.Api.Models.Internal.ChatConnectionStringBuilder that dictates how to form it

For IRC chat bots see Tgstation.Server.Api.Models.IrcConnectionStringBuilder For Discord chat bots see Tgstation.Server.Api.Models.DiscordConnectionStringBuilder

A specific bot's settings may be retrieved with:

I GET "/Chat/{ChatBotId}" => Tgstation.Server.Api.Models.ChatBot

Also note that if the Tgstation.Server.Api.Models.ChatBot.Channels is present in a POST request, the list will fully replace any active channels

Byond Version Management

To get the Byond version used for new compilations use the following request:

I GET "/Byond" => Tgstation.Server.Api.Models.Byond

To set the active Byond version:

I POST "/Byond" Tgstation.Server.Api.Models.Byond => Tgstation.Server.Api.Models.Byond

This will queue up a job to install the byond version if it doesn't exist which will be returned in the response. The Tgstation.Server.Api.Models.Internal.RawData.Content field can be used to upload custom zip files.

To list all installed Byond versions use the following request:

I GET "/Byond/List" => Array of Tgstation.Server.Api.Models.Byond

Repository Management

To read the current repository state use the following request:

I GET "/Repository" => Tgstation.Server.Api.Models.Repository

To clone the repository if it doesn't yet exist use the following request:

I PUT "/Repository" => Tgstation.Server.Api.Models.Repository

The clone job will be represented by the Tgstation.Server.Api.Models.Repository.ActiveJob field. Specify the Tgstation.Server.Api.Models.Repository.Origin URL. Optionally specify the initial Tgstation.Server.Api.Models.Repository.Reference as a git tag or branch. Be sure to specify the authentication fields if necessary to access your repository. Will return 409 if the repository already exists or is already being cloned

To delete an existing repository make the following request:

I DELETE "/Repository" => OK

Modifications to the repository are done with the following request:

I POST "/Repository" => Tgstation.Server.Api.Models.Repository => Tgstation.Server.Api.Models.Repository

Each update that requires git changes creates a job specified in the Tgstation.Server.Api.Models.Repository.ActiveJob field jobs will be queued in succession. See below for POST examples.

Repository Commands for Git Aliases

All these actions are done with the POST method

git pull (Only if Tgstation.Server.Api.Models.Repository.Reference is set):

{
"updateFromOrigin": true
}

git checkout <commit sha> (Unsets Tgstation.Server.Api.Models.Repository.Reference):

{
"checkoutSha": "<commit sha>"
}

git checkout -f <branch or tag> && git clean -fxd (Sets Tgstation.Server.Api.Models.Repository.Reference):

{
"reference": "<branch or tag>"
}

git fetch && git checkout -f branch && git clean -fxd && git reset –hard origin/branch (Sets Tgstation.Server.Api.Models.Repository.Reference);

{
"updateFromOrigin": true,
"reference": "branch"
}

Test Merging

Any of the above POST methods can be combined with the Tgstation.Server.Api.Models.Repository.NewTestMerges field to add test merges on top of the checked out commit.

{
"newTestMerges": [
{
"number": 12345,
"comment": "I'm merging this for x reason"
},
{
"number": 12346,
"pullRequestRevision": "abcdef1"
}
]
}

If the server detects a set of Tgstation.Server.Api.Models.TestMergeParameters being applied that it has seen before, it'll instead attempt to checkout the commit that was created then.

Unsetting Authentication

The repository uses the Tgstation.Server.Api.Models.Repository.AccessUser and Tgstation.Server.Api.Models.Repository.AccessToken credentials to access the remote repository if these fields are set. To unset them you must set both of them to an empty string like so

{
"accessUser": "",
"accessToken": ""
}

This will remove both fields from the database

Compiler Handling

The DM compiler can run one job at a time for an Instance. Instead of using standard Tgstation.Server.Api.Models.Job.Progress it uses the Tgstation.Server.Api.Models.DreamMaker.Status field to denote it's current stage. It can be retrieved like this:

I GET "/DreamMaker" => Tgstation.Server.Api.Models.DreamMaker

This will also return the last successful Tgstation.Server.Api.Models.CompileJob as well as the Tgstation.Server.Api.Models.Internal.DreamMakerSettings.ProjectName

The ProjectName field can be changed with this method:

I POST "/DreamMaker" Tgstation.Server.Api.Models.DreamMaker => Tgstation.Server.Api.Models.DreamMaker

To start a compile job use the following request:

I PUT "/DreamMaker" Empty => Tgstation.Server.Api.Models.Job

The job object returned represents the compile job

"Empty" refers to an empty json object like so:

{}

The compiler endpoint is also used to read compile jobs

To list successful compile jobs ids use:

I GET "/DreamMaker/List" => Array of Tgstation.Server.Api.Models.CompileJob

To get a specific compile job use:

I GET "/DreamMaker/{CompileJobId}" => Tgstation.Server.Api.Models.CompileJob

Static Files

Static files can be both read and written.

To get the contents of a static file directory use the following method

I GET "/Config/List/<path to directory>" => Array of Tgstation.Server.Api.Models.ConfigurationFile

Where the path is formatted as: directory/inner_directory/more_directories

If the path is empty, the root directory will be retrieved. The Tgstation.Server.Api.Models.ConfigurationFile.Content and Tgstation.Server.Api.Models.ConfigurationFile.LastReadHash fields will not be populated for this response

If you do not have access to list the requested directory, a 403 response will be returned. If the path actually represents a file or the directory no longer exists a 410 response will be returned.

To create an empty config directory use the following request

I PUT "/Config" Tgstation.Server.Api.Models.ConfigurationFile => Tgstation.Server.Api.Models.ConfigurationFile

To get the content of a static file use the following method

I GET "/Config/File/<path to file>" => Tgstation.Server.Api.Models.ConfigurationFile

410 will be returned if the path doesn't exist. Tgstation.Server.Api.Models.ConfigurationFile.Content will only be populated if the path is a file the user has access to, otherwise the other fields will be populated appropriately.

To create, write, and delete files use the following request

I POST "/Config" Tgstation.Server.Api.Models.ConfigurationFile => Tgstation.Server.Api.Models.ConfigurationFile

When creating a file, only Tgstation.Server.Api.Models.ConfigurationFile.Path and Tgstation.Server.Api.Models.ConfigurationFile.Content should be specified

If the file already exists, the Tgstation.Server.Api.Models.ConfigurationFile.LastReadHash field must also be present with the last version received from the server for that file. If this does not match at the time of the request, 409 will be returned, indicating the file has changed since it was last viewed by the client.

To delete a file set Tgstation.Server.Api.Models.ConfigurationFile.Content to null in the request.

To delete an empty directory use the following request

I DELETE "/Config" Tgstation.Server.Api.Models.ConfigurationFile => OK

Where the request Tgstation.Server.Api.Models.ConfigurationFile.Path is set to the directory to delete

Watchdog

To read watchdog status use the following request:

I GET "/DreamDaemon" => Tgstation.Server.Api.Models.DreamDaemon

To update watchdog settings use the following request:

I POST "/DreamDaemon" => Tgstation.Server.Api.Models.DreamDaemon

Note that soft restart/shutdown operations cannot be cancelled via this method, they can be changed from one to another however.

To start the watchdog use the following request:

I PUT "/DreamDaemon" Empty => Tgstation.Server.Api.Models.Job

To restart the watchdog use the following request:

I PATCH "/DreamDaemon" Empty => Tgstation.Server.Api.Models.Job

The returned jobs represents the startup process for the watchdog

To stop the watchdog use the following request:

I DELETE "/DreamDaemon" => OK