curl --request POST \
--url https://api.simpl.gg/v1/builds/upload-url \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--data '
{
"name": "1.2.3",
"executable_path": "Linux/GameServer.sh"
}
'import requests
url = "https://api.simpl.gg/v1/builds/upload-url"
payload = {
"name": "1.2.3",
"executable_path": "Linux/GameServer.sh"
}
headers = {
"api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '1.2.3', executable_path: 'Linux/GameServer.sh'})
};
fetch('https://api.simpl.gg/v1/builds/upload-url', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.simpl.gg/v1/builds/upload-url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '1.2.3',
'executable_path' => 'Linux/GameServer.sh'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.simpl.gg/v1/builds/upload-url"
payload := strings.NewReader("{\n \"name\": \"1.2.3\",\n \"executable_path\": \"Linux/GameServer.sh\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.simpl.gg/v1/builds/upload-url")
.header("api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"1.2.3\",\n \"executable_path\": \"Linux/GameServer.sh\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.simpl.gg/v1/builds/upload-url")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"1.2.3\",\n \"executable_path\": \"Linux/GameServer.sh\"\n}"
response = http.request(request)
puts response.read_body{
"build_id": "build_9f2c",
"upload_url": "<string>",
"expires_at": "2023-11-07T05:31:56Z",
"build": {
"build_id": "build_9f2c",
"name": "1.2.3",
"version": 12,
"status": "uploading",
"build_type": "zip",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"executable_path": "Linux/GameServer.sh",
"image_url": "registry.example.com/game/server:1.2.3",
"error_message": "No executable found at Linux/GameServer.sh",
"base_version": "2"
}
}Create a ZIP build upload URL
Creates a build in uploading state and returns a pre-signed URL to
PUT the ZIP archive to. Once the upload completes the build moves to
processing, then ready or failed. Poll
GET /v1/builds/{build_id} to follow processing; a failed build
explains itself in error_message.
/simpl/its_simpl.json is written into ZIP builds at the same absolute
path as Docker builds: always /simpl/its_simpl.json.
curl --request POST \
--url https://api.simpl.gg/v1/builds/upload-url \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--data '
{
"name": "1.2.3",
"executable_path": "Linux/GameServer.sh"
}
'import requests
url = "https://api.simpl.gg/v1/builds/upload-url"
payload = {
"name": "1.2.3",
"executable_path": "Linux/GameServer.sh"
}
headers = {
"api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '1.2.3', executable_path: 'Linux/GameServer.sh'})
};
fetch('https://api.simpl.gg/v1/builds/upload-url', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.simpl.gg/v1/builds/upload-url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '1.2.3',
'executable_path' => 'Linux/GameServer.sh'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.simpl.gg/v1/builds/upload-url"
payload := strings.NewReader("{\n \"name\": \"1.2.3\",\n \"executable_path\": \"Linux/GameServer.sh\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.simpl.gg/v1/builds/upload-url")
.header("api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"1.2.3\",\n \"executable_path\": \"Linux/GameServer.sh\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.simpl.gg/v1/builds/upload-url")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"1.2.3\",\n \"executable_path\": \"Linux/GameServer.sh\"\n}"
response = http.request(request)
puts response.read_body{
"build_id": "build_9f2c",
"upload_url": "<string>",
"expires_at": "2023-11-07T05:31:56Z",
"build": {
"build_id": "build_9f2c",
"name": "1.2.3",
"version": 12,
"status": "uploading",
"build_type": "zip",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"executable_path": "Linux/GameServer.sh",
"image_url": "registry.example.com/game/server:1.2.3",
"error_message": "No executable found at Linux/GameServer.sh",
"base_version": "2"
}
}Authorizations
Per-project server key, prefixed sk_live_. Full access to every
endpoint. Keep it on your backend: never ship it in a game binary.
Query Parameters
Which project to act on. Required when authenticating with a developer
session (bearer_auth), which names no project of its own; ignored when
authenticating with an API key, which carries its project already.
A project belonging to another account returns PROJECT_NOT_FOUND (7001)
rather than a 403, so this cannot be used to probe for project ids.
"proj_abc123"
Body
Request a pre-signed URL to upload a ZIP build to.
"1.2.3"
Path to the server executable inside the uploaded ZIP.
"Linux/GameServer.sh"
Ports every server started from this build exposes. Each entry takes only
a name and a protocol: there is no port number, because each server
gets its own external port numbers when it starts. They are in
network_ports, and the port the game listens on for each name is the
project's (ProjectPort).
The game port is the port named game, or the first declared port if
none is. Its number is always in SIMPL_PORT_GAME, which is what the
Simpl entrypoint's {{PORT}} and the starter scripts read.
1 - 8 elementsShow child attributes
Show child attributes
Command-line arguments for every server started from this build.
- ZIP build: baked into the image after the executable.
- docker_image build: appended to the image's own
ENTRYPOINTandCMDwhen each server starts.
For both, the Simpl entrypoint substitutes placeholders such as
{{PORT}} in them.
A server's startup_args come after these.
641024["-log"]