curl --request POST \
--url https://sailbox-api.sailresearch.com/v1/http-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "github",
"document": {
"api.github.com": {
"rules": [
{
"request": {
"set": {
"headers": {
"authorization": "Bearer ${secrets.GITHUB_TOKEN}"
}
}
}
}
]
}
}
}
'import requests
url = "https://sailbox-api.sailresearch.com/v1/http-policies"
payload = {
"name": "github",
"document": { "api.github.com": { "rules": [{ "request": { "set": { "headers": { "authorization": "Bearer ${secrets.GITHUB_TOKEN}" } } } }] } }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'github',
document: {
'api.github.com': {
rules: [{request: {set: {headers: {authorization: 'Bearer ${secrets.GITHUB_TOKEN}'}}}}]
}
}
})
};
fetch('https://sailbox-api.sailresearch.com/v1/http-policies', 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/http-policies",
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' => 'github',
'document' => [
'api.github.com' => [
'rules' => [
[
'request' => [
'set' => [
'headers' => [
'authorization' => 'Bearer ${secrets.GITHUB_TOKEN}'
]
]
]
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://sailbox-api.sailresearch.com/v1/http-policies"
payload := strings.NewReader("{\n \"name\": \"github\",\n \"document\": {\n \"api.github.com\": {\n \"rules\": [\n {\n \"request\": {\n \"set\": {\n \"headers\": {\n \"authorization\": \"Bearer ${secrets.GITHUB_TOKEN}\"\n }\n }\n }\n }\n ]\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://sailbox-api.sailresearch.com/v1/http-policies")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"github\",\n \"document\": {\n \"api.github.com\": {\n \"rules\": [\n {\n \"request\": {\n \"set\": {\n \"headers\": {\n \"authorization\": \"Bearer ${secrets.GITHUB_TOKEN}\"\n }\n }\n }\n }\n ]\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/http-policies")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"github\",\n \"document\": {\n \"api.github.com\": {\n \"rules\": [\n {\n \"request\": {\n \"set\": {\n \"headers\": {\n \"authorization\": \"Bearer ${secrets.GITHUB_TOKEN}\"\n }\n }\n }\n }\n ]\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"org_id": "<string>",
"name": "<string>",
"document": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": {
"message": "name is required",
"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": "request body too large",
"type": "invalid_request_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": "create HTTP policy failed",
"type": "server_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Authentication service unavailable",
"type": "server_error",
"param": null,
"code": null
}
}Create an HTTP policy
Creates a named policy for your organization. Every secret named in the document must already exist. A policy document cannot change after creation, but its name can. Sail saves a normalized form of the document (for example, host names are lowercased and defaults are filled in), so reading the policy back can return a different shape with the same behavior.
curl --request POST \
--url https://sailbox-api.sailresearch.com/v1/http-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "github",
"document": {
"api.github.com": {
"rules": [
{
"request": {
"set": {
"headers": {
"authorization": "Bearer ${secrets.GITHUB_TOKEN}"
}
}
}
}
]
}
}
}
'import requests
url = "https://sailbox-api.sailresearch.com/v1/http-policies"
payload = {
"name": "github",
"document": { "api.github.com": { "rules": [{ "request": { "set": { "headers": { "authorization": "Bearer ${secrets.GITHUB_TOKEN}" } } } }] } }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'github',
document: {
'api.github.com': {
rules: [{request: {set: {headers: {authorization: 'Bearer ${secrets.GITHUB_TOKEN}'}}}}]
}
}
})
};
fetch('https://sailbox-api.sailresearch.com/v1/http-policies', 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/http-policies",
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' => 'github',
'document' => [
'api.github.com' => [
'rules' => [
[
'request' => [
'set' => [
'headers' => [
'authorization' => 'Bearer ${secrets.GITHUB_TOKEN}'
]
]
]
]
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://sailbox-api.sailresearch.com/v1/http-policies"
payload := strings.NewReader("{\n \"name\": \"github\",\n \"document\": {\n \"api.github.com\": {\n \"rules\": [\n {\n \"request\": {\n \"set\": {\n \"headers\": {\n \"authorization\": \"Bearer ${secrets.GITHUB_TOKEN}\"\n }\n }\n }\n }\n ]\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://sailbox-api.sailresearch.com/v1/http-policies")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"github\",\n \"document\": {\n \"api.github.com\": {\n \"rules\": [\n {\n \"request\": {\n \"set\": {\n \"headers\": {\n \"authorization\": \"Bearer ${secrets.GITHUB_TOKEN}\"\n }\n }\n }\n }\n ]\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/http-policies")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"github\",\n \"document\": {\n \"api.github.com\": {\n \"rules\": [\n {\n \"request\": {\n \"set\": {\n \"headers\": {\n \"authorization\": \"Bearer ${secrets.GITHUB_TOKEN}\"\n }\n }\n }\n }\n ]\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"org_id": "<string>",
"name": "<string>",
"document": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": {
"message": "name is required",
"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": "request body too large",
"type": "invalid_request_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": "create HTTP policy failed",
"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.
Body
Display name. It does not need to be unique. It must contain visible text and cannot contain tabs, line breaks, or other control characters. At most 128 characters after surrounding whitespace is trimmed.
1^(?=[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*[^\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000])[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*[^\u0000-\u001F\u007F-\u009F]+[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$Host patterns mapped to rules. Use an exact hostname, *.example.com for one direct subdomain, or * for anything not matched earlier. A hostname is at most 253 characters. A document can contain at most 100 rules in total and is at most 64 KiB when encoded.
Show child attributes
Show child attributes
Response
The policy.
Stable policy ID.
^hp_[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$Organization that owns the policy.
Display name.
Host patterns mapped to rules. Use an exact hostname, *.example.com for one direct subdomain, or * for anything not matched earlier. A hostname is at most 253 characters. A document can contain at most 100 rules in total and is at most 64 KiB when encoded.
Show child attributes
Show child attributes
When the policy was created.
When the policy name last changed.