curl --request POST \
--url https://network.{region}.basaltic.sh/v1/nat-gateways \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "main",
"subnet": "7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d",
"description": "NAT gateway for private subnet egress",
"tags": {}
}
'import requests
url = "https://network.{region}.basaltic.sh/v1/nat-gateways"
payload = {
"name": "main",
"subnet": "7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d",
"description": "NAT gateway for private subnet egress",
"tags": {}
}
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: 'main',
subnet: '7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d',
description: 'NAT gateway for private subnet egress',
tags: {}
})
};
fetch('https://network.{region}.basaltic.sh/v1/nat-gateways', 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://network.{region}.basaltic.sh/v1/nat-gateways",
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' => 'main',
'subnet' => '7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d',
'description' => 'NAT gateway for private subnet egress',
'tags' => [
]
]),
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://network.{region}.basaltic.sh/v1/nat-gateways"
payload := strings.NewReader("{\n \"name\": \"main\",\n \"subnet\": \"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d\",\n \"description\": \"NAT gateway for private subnet egress\",\n \"tags\": {}\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://network.{region}.basaltic.sh/v1/nat-gateways")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"main\",\n \"subnet\": \"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d\",\n \"description\": \"NAT gateway for private subnet egress\",\n \"tags\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://network.{region}.basaltic.sh/v1/nat-gateways")
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\": \"main\",\n \"subnet\": \"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d\",\n \"description\": \"NAT gateway for private subnet egress\",\n \"tags\": {}\n}"
response = http.request(request)
puts response.read_body{
"nat_gateway": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:nat-gateway/main",
"name": "main",
"subnet": {
"id": "288aa1e9-bbf5-5584-bce9-6a688f06d8a1",
"crn": "crn:catalog::platform:country/288aa1e9-bbf5-5584-bce9-6a688f06d8a1",
"name": "Brazil"
},
"public_ipv4": "203.0.113.10",
"tags": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "NAT gateway for private subnet egress",
"public_ipv6": "2001:db8:ffff::10"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "CONFLICT",
"message": "Resource with this name already exists",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "IDEMPOTENCY_KEY_REUSED",
"message": "This Idempotency-Key was already used with a different request payload",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Create NAT gateway
Allocates public IPv4 and, when the hosting subnet has IPv6, public IPv6 from the regional tenant pool. Enabling IPv6 on the hosting subnet later also assigns the gateway’s public IPv6. Both addresses are stable until gateway deletion and count against their family’s public IP quota. Allocation does not depend on routes. Subnets use the gateway for shared source NAT by routing 0.0.0.0/0 or ::/0 to it. IPv6 source NAT supports ULA and global addresses. The target VPC must already have an Internet Gateway attached.
curl --request POST \
--url https://network.{region}.basaltic.sh/v1/nat-gateways \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "main",
"subnet": "7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d",
"description": "NAT gateway for private subnet egress",
"tags": {}
}
'import requests
url = "https://network.{region}.basaltic.sh/v1/nat-gateways"
payload = {
"name": "main",
"subnet": "7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d",
"description": "NAT gateway for private subnet egress",
"tags": {}
}
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: 'main',
subnet: '7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d',
description: 'NAT gateway for private subnet egress',
tags: {}
})
};
fetch('https://network.{region}.basaltic.sh/v1/nat-gateways', 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://network.{region}.basaltic.sh/v1/nat-gateways",
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' => 'main',
'subnet' => '7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d',
'description' => 'NAT gateway for private subnet egress',
'tags' => [
]
]),
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://network.{region}.basaltic.sh/v1/nat-gateways"
payload := strings.NewReader("{\n \"name\": \"main\",\n \"subnet\": \"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d\",\n \"description\": \"NAT gateway for private subnet egress\",\n \"tags\": {}\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://network.{region}.basaltic.sh/v1/nat-gateways")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"main\",\n \"subnet\": \"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d\",\n \"description\": \"NAT gateway for private subnet egress\",\n \"tags\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://network.{region}.basaltic.sh/v1/nat-gateways")
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\": \"main\",\n \"subnet\": \"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d\",\n \"description\": \"NAT gateway for private subnet egress\",\n \"tags\": {}\n}"
response = http.request(request)
puts response.read_body{
"nat_gateway": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:nat-gateway/main",
"name": "main",
"subnet": {
"id": "288aa1e9-bbf5-5584-bce9-6a688f06d8a1",
"crn": "crn:catalog::platform:country/288aa1e9-bbf5-5584-bce9-6a688f06d8a1",
"name": "Brazil"
},
"public_ipv4": "203.0.113.10",
"tags": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "NAT gateway for private subnet egress",
"public_ipv6": "2001:db8:ffff::10"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "CONFLICT",
"message": "Resource with this name already exists",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "IDEMPOTENCY_KEY_REUSED",
"message": "This Idempotency-Key was already used with a different request payload",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}network:CreateNATGateway. See NETWORK permissions for the full list, what each one covers, and an example policy.Authorizations
An OAuth 2.0 bearer token, sent as Authorization: Bearer <token>.
This is the recommended way to authenticate.
Get one by exchanging a service account's access key pair at
POST /v1/oauth/token with grant_type=client_credentials. It is the
standard client-credentials grant, so any OAuth-aware library will
obtain and refresh it for you.
curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
https://iam.basaltic.sh/v1/oauth/token
Tokens last an hour by default. The same access key pair is separately your AWS SigV4 credential for the S3-compatible object endpoint, which speaks nothing else.
Headers
Optional client-generated key that makes a create replay-safe. Retrying a request with the same key returns the original outcome verbatim instead of creating a duplicate resource. Reusing a key with a different request body is rejected (422); a request whose key is still being processed returns 409. Records are honored for 24 hours. Use a UUID or similarly unique token.
255Body
Resource names must not start with the literal crn: prefix or be UUIDs (canonical, compact, braced, or urn:uuid: forms, in either case).
"main"
Subnet UUID or nested CRN (vpc//subnet/). A bare name requires an explicit VPC filter; create requests without a VPC do not accept bare names.
"7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d"
"NAT gateway for private subnet egress"
Show child attributes
Show child attributes
Response
NAT gateway created
Show child attributes
Show child attributes

