curl --request GET \
--url https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port} \
--header 'Authorization: Bearer <token>'import requests
url = "https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}', 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://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"guest_port": 123,
"protocol": "<string>",
"route_status": "<string>",
"public_url": "https://sb-9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d-8000.sail.box",
"public_host": "<string>",
"public_port": 123,
"allowlist": [
"<string>"
]
}{
"error": {
"message": "memory_limit_gib for size m must be between 8 and 128",
"type": "invalid_request_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}{
"error": {
"message": "Your API key has been disabled due to insufficient credits. Visit https://app.sailresearch.com/billing to add credits.",
"type": "billing_error",
"param": null,
"code": "credits_exhausted",
"billing_url": "https://app.sailresearch.com/billing"
}
}{
"error": {
"message": "sailboxes require an organization-scoped API key",
"type": "permission_error",
"param": null,
"code": null
}
}{
"error": {
"message": "sailbox \"sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d\" not found",
"type": "not_found_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Too many concurrent requests. Please retry after some of your organization's in-flight requests complete.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limited"
}
}{
"error": {
"message": "failed to fetch sailbox",
"type": "server_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Authentication service unavailable",
"type": "server_error",
"param": null,
"code": null
}
}Retrieve a published port
Returns one published port and the address to reach it.
curl --request GET \
--url https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port} \
--header 'Authorization: Bearer <token>'import requests
url = "https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}', 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://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/listeners/{guest_port}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"guest_port": 123,
"protocol": "<string>",
"route_status": "<string>",
"public_url": "https://sb-9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d-8000.sail.box",
"public_host": "<string>",
"public_port": 123,
"allowlist": [
"<string>"
]
}{
"error": {
"message": "memory_limit_gib for size m must be between 8 and 128",
"type": "invalid_request_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}{
"error": {
"message": "Your API key has been disabled due to insufficient credits. Visit https://app.sailresearch.com/billing to add credits.",
"type": "billing_error",
"param": null,
"code": "credits_exhausted",
"billing_url": "https://app.sailresearch.com/billing"
}
}{
"error": {
"message": "sailboxes require an organization-scoped API key",
"type": "permission_error",
"param": null,
"code": null
}
}{
"error": {
"message": "sailbox \"sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d\" not found",
"type": "not_found_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Too many concurrent requests. Please retry after some of your organization's in-flight requests complete.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limited"
}
}{
"error": {
"message": "failed to fetch sailbox",
"type": "server_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Authentication service unavailable",
"type": "server_error",
"param": null,
"code": null
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Id of the Sailbox, as returned by create. It is sb_ followed by a UUID.
Port inside the Sailbox that the listener sends traffic to.
1 <= x <= 65535Response
The published port.
Port inside the Sailbox that traffic is sent to.
Protocol the listener serves. Values in use today are http and tcp. New values can appear over time, so treat this as an open set.
Whether the Sailbox behind this listener is up. LISTENER_ROUTE_STATUS_ACTIVE means it is running and traffic is being routed to it. LISTENER_ROUTE_STATUS_PENDING means it is still starting. LISTENER_ROUTE_STATUS_UNAVAILABLE means the address is held for the Sailbox but nothing is routed there, which is what you see any time it is not running, such as while it is paused or sleeping. This tracks the Sailbox, not the process inside it, so an active route with nothing listening on the port still fails to answer. New values can appear over time, so treat this as an open set.
HTTPS URL for an http listener.
"https://sb-9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d-8000.sail.box"
Host to dial for a tcp listener.
Port to dial for a tcp listener.
Sources allowed to reach the listener: addresses, ranges, and app names.