Domains
Domains and contacts as InfraNest knows them. Registrar actions (register, renew, transfer) stay in the app.
Common tasks
Only in the app: Registering, renewing and transferring domains, nameservers and registrar settings.
How it works in the app: help article.
Scopes: Read with domains.read, change with domains.write. See Tokens and scopes.
Contacts 5 · Domain findings 1 · Domains 26
Every endpoint below takes a token in the Authorization: Bearer header and answers JSON. Errors use the shared format in Errors. Base address: https://api.infranest.io/api.
Contacts
List contacts
Your organization’s contacts, paginated with page and per_page (up to 200), with their tags. Filter with search or tag, and sort with sort (name, company, email, city, country) and dir.
/organizations/{organization}/contactsdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/contacts" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/contacts" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/contacts', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/contacts",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/contacts', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/contacts", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"current_page": 1,
"data": [
{
"id": 1,
"organization_id": 1,
"first_name": "Alex",
"last_name": "Rivera",
"company": "Northwind Cloud",
"email": "domains@northwind.example",
"phone": "+31 20 555 0123",
"address": "Keizersgracht",
"city": "Amsterdam",
"state": null,
"zip": "1015 CJ",
"country": "NL",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"house_number": "123",
"vat_number": null,
"company_number": null,
"missing_for_registration": [],
"tags": []
},
{
"id": 3,
"organization_id": 1,
"first_name": "Priya",
"last_name": "Nair",
"company": "Northwind Cloud",
"email": "legal@northwind.example",
"phone": "+44 20 7946 0321",
"address": "Shoreditch High Street",
"city": "London",
"state": "Greater London",
"zip": "E1 6JJ",
"country": "GB",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"house_number": "42",
"vat_number": null,
"company_number": null,
"missing_for_registration": [],
"tags": []
}
],
"first_page_url": "http://localhost/api/organizations/1/contacts?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "http://localhost/api/organizations/1/contacts?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "http://localhost/api/organizations/1/contacts?page=1",
"label": "1",
"page": 1,
"active": true
}
],
"next_page_url": null,
"path": "http://localhost/api/organizations/1/contacts",
"per_page": 25,
"prev_page_url": null,
"to": 4,
"total": 4,
"meta": {
"tags": []
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Create a contact
Creates a contact you can assign to domains as registrant, admin, tech or billing contact, optionally tagged with tag_ids.
/organizations/{organization}/contactsdomains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Bodyapplication/json
first_namestringrequiredMust not be greater than 100 characters.
last_namestringrequiredMust not be greater than 100 characters.
companystring, nullableoptionalMust not be greater than 255 characters.
vat_numberstring, nullableoptionalMust not be greater than 50 characters.
company_numberstring, nullableoptionalMust not be greater than 50 characters.
emailstringrequiredMust be a valid email address. Must not be greater than 255 characters.
phonestring, nullableoptionalMust not be greater than 50 characters.
addressstring, nullableoptionalMust not be greater than 255 characters.
house_numberstring, nullableoptionalMust not be greater than 20 characters.
citystring, nullableoptionalMust not be greater than 100 characters.
statestring, nullableoptionalMust not be greater than 100 characters.
zipstring, nullableoptionalMust not be greater than 20 characters.
countrystringrequiredMust be 2 characters.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/contacts" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"first_name":"Ada","last_name":"Brandt","email":"ada@northwind.example","country":"DE"}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"first_name": "Ada",
"last_name": "Brandt",
"email": "ada@northwind.example",
"country": "DE"
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/contacts" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/contacts', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'first_name' => 'Ada',
'last_name' => 'Brandt',
'email' => 'ada@northwind.example',
'country' => 'DE',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/contacts",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"first_name": "Ada",
"last_name": "Brandt",
"email": "ada@northwind.example",
"country": "DE",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/contacts', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"first_name": "Ada",
"last_name": "Brandt",
"email": "ada@northwind.example",
"country": "DE"
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/contacts", strings.NewReader(`{"first_name":"Ada","last_name":"Brandt","email":"ada@northwind.example","country":"DE"}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"first_name": "Ada",
"last_name": "Brandt",
"email": "ada@northwind.example",
"country": "DE",
"organization_id": 1,
"updated_at": "2026-01-15T12:00:00.000000Z",
"created_at": "2026-01-15T12:00:00.000000Z",
"id": 5,
"missing_for_registration": [
"address",
"city"
],
"tags": []
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The first name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"first_name": [
"The first name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Get a contact
One contact with the domains it is assigned to.
/organizations/{organization}/contacts/{id}domains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
idintegerrequiredThe id's ID.
Request
curl "https://api.infranest.io/api/organizations/42/contacts/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/contacts/1" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/contacts/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/contacts/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/contacts/1', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/contacts/1", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"first_name": "Alex",
"last_name": "Rivera",
"company": "Northwind Cloud",
"email": "domains@northwind.example",
"phone": "+31 20 555 0123",
"address": "Keizersgracht",
"city": "Amsterdam",
"state": null,
"zip": "1015 CJ",
"country": "NL",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"house_number": "123",
"vat_number": null,
"company_number": null,
"missing_for_registration": [],
"domains": []
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Update a contact
Updates the contact and, when tag_ids is sent, its tags. Recorded in InfraNest only; nothing is sent to a registrar.
/organizations/{organization}/contacts/{id}domains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
idintegerrequiredThe id's ID.
Bodyapplication/json
first_namestringoptionalMust not be greater than 100 characters.
last_namestringoptionalMust not be greater than 100 characters.
companystring, nullableoptionalMust not be greater than 255 characters.
vat_numberstring, nullableoptionalMust not be greater than 50 characters.
company_numberstring, nullableoptionalMust not be greater than 50 characters.
emailstringoptionalMust be a valid email address. Must not be greater than 255 characters.
phonestring, nullableoptionalMust not be greater than 50 characters.
addressstring, nullableoptionalMust not be greater than 255 characters.
house_numberstring, nullableoptionalMust not be greater than 20 characters.
citystring, nullableoptionalMust not be greater than 100 characters.
statestring, nullableoptionalMust not be greater than 100 characters.
zipstring, nullableoptionalMust not be greater than 20 characters.
countrystringoptionalMust be 2 characters.
Request
curl -X PUT "https://api.infranest.io/api/organizations/42/contacts/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"company":"Northwind Cloud GmbH","city":"Köln"}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"company": "Northwind Cloud GmbH",
"city": "Köln"
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/contacts/1" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/contacts/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'company' => 'Northwind Cloud GmbH',
'city' => 'Köln',
],
]);
echo $response->getBody();import os
import requests
response = requests.put(
"https://api.infranest.io/api/organizations/42/contacts/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"company": "Northwind Cloud GmbH",
"city": "Köln",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/contacts/1', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"company": "Northwind Cloud GmbH",
"city": "Köln"
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/contacts/1", strings.NewReader(`{"company":"Northwind Cloud GmbH","city":"Köln"}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"first_name": "Alex",
"last_name": "Rivera",
"company": "Northwind Cloud GmbH",
"email": "domains@northwind.example",
"phone": "+31 20 555 0123",
"address": "Keizersgracht",
"city": "Köln",
"state": null,
"zip": "1015 CJ",
"country": "NL",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"house_number": "123",
"vat_number": null,
"company_number": null,
"missing_for_registration": [],
"tags": []
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The first name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"first_name": [
"The first name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited
Delete a contact
Deletes the contact from your organization.
/organizations/{organization}/contacts/{id}domains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
idintegerrequiredThe id's ID.
Request
curl -X DELETE "https://api.infranest.io/api/organizations/42/contacts/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/contacts/1" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/contacts/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.delete(
"https://api.infranest.io/api/organizations/42/contacts/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.status_code)const response = await fetch('https://api.infranest.io/api/organizations/42/contacts/1', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/contacts/1", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
No content.{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited
Domain findings
List domain findings
Advisor findings across all your domains, most urgent first, with one finding per cause naming every domain it affects.
/organizations/{organization}/domain-findingsdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/domain-findings" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domain-findings" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domain-findings', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domain-findings",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domain-findings', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domain-findings", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"data": [
{
"key": "expiry",
"check": "expiry",
"status": "error",
"variant": "lapsed",
"params": {
"days": -6,
"expires_at": "2026-01-09"
},
"action": "renew",
"cause": "domain:18:expiry",
"rank": 390,
"home": {
"source": "domain_expiring",
"key": "domain:18",
"fingerprint": "2026-01-09"
},
"snoozed": false,
"domains": [
{
"id": 18,
"name": "nwcloud.app"
}
]
},
{
"key": "dnssec",
"check": "dnssec",
"status": "error",
"variant": "notValidating",
"params": {
"since": "2026-01-13T12:00:00.000000Z"
},
"action": null,
"cause": "domain:9:dnssec",
"rank": 350,
"home": {
"source": "dnssec_broken",
"key": "dnssec_broken:9",
"fingerprint": ""
},
"snoozed": false,
"domains": [
{
"id": 9,
"name": "northwind.de"
}
]
}
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Domains
List domains
Your domains, paginated with page and per_page (up to 200), each with its tags, advisor issue count and who hosts its website and mail. Filter with search, credential, tag, active, expiring_soon, autorenew_off, website, mail or archived (archived domains are left out unless asked for). Registration orders that failed are not domains you hold and are left out too; pass include_failed=1 to list them, and meta.counts.failed says how many there are. Sort with sort (domain, registrar, expires) and dir.
/organizations/{organization}/domainsdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/domains" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"current_page": 1,
"data": [
{
"id": 11,
"organization_id": 1,
"name": "northwind",
"tld": "cloud",
"registrar": "Porkbun",
"registered_at": "2024-01-14T00:00:00.000000Z",
"expires_at": "2026-11-12T00:00:00.000000Z",
"auto_renew": true,
"status": "active",
"notes": null,
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": [
"hydrogen.ns.hetzner.com",
"oxygen.ns.hetzner.com"
],
"transfer_lock": true,
"whois_privacy": true,
"registrar_contacts": null,
"dnssec_entries": null,
"has_dnssec": null,
"renewal_price": "22.00",
"renewal_price_currency": "EUR",
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "manual",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": null,
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": null,
"dnssec_checked_at": null,
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"custom_fields": {
"1": "Marketing"
},
"advisor_issues": 0,
"uses": {
"website": {
"kind": "server",
"label": "web-01",
"url": "/servers/1",
"flagged": false,
"since": null,
"provider": "Hetzner",
"note": null,
"ours": false
},
"site": {
"key": "host:hetzner",
"label": "Hetzner"
},
"mail": {
"key": "none",
"label": null
},
"no_zone": null
},
"full_name": "northwind.cloud",
"archivable": true,
"dns_host": "hetzner",
"management": "tracked",
"sync_halt": null,
"provider_credential": null,
"tags": [
{
"id": 4,
"name": "Internal",
"color": "#8b5cf6",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 11,
"tag_id": 4
}
}
]
},
{
"id": 1,
"organization_id": 1,
"name": "northwind",
"tld": "com",
"registrar": "Namecheap",
"registered_at": "2023-12-28T00:00:00.000000Z",
"expires_at": "2026-02-02T00:00:00.000000Z",
"auto_renew": true,
"status": "active",
"notes": null,
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"transfer_lock": true,
"whois_privacy": true,
"registrar_contacts": null,
"dnssec_entries": [
{
"key_tag": 62949,
"algorithm": 13,
"digest_type": 2,
"digest": "FBF66B8D019C1EEC1E1A0B5A9D3C2E7F4A8B60D5C93E71F2A6B8D04C7E19A35B"
}
],
"has_dnssec": true,
"renewal_price": "12.50",
"renewal_price_currency": "EUR",
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "manual",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": null,
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": "signed",
"dnssec_checked_at": "2026-01-15T11:25:00.000000Z",
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"custom_fields": {
"1": "Marketing"
},
"advisor_issues": 0,
"uses": {
"website": {
"kind": "server",
"label": "web-01",
"url": "/servers/1",
"flagged": false,
"since": null,
"provider": "Hetzner",
"note": {
"key": "proxied",
"params": {
"provider": "Cloudflare"
}
},
"ours": false
},
"site": {
"key": "host:hetzner",
"label": "Hetzner"
},
"mail": {
"key": "other",
"label": "mx.northwind.com"
},
"no_zone": null
},
"full_name": "northwind.com",
"archivable": true,
"dns_host": "cloudflare",
"management": "tracked",
"sync_halt": null,
"provider_credential": null,
"tags": [
{
"id": 3,
"name": "Customer-facing",
"color": "#3b82f6",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 1,
"tag_id": 3
}
},
{
"id": 5,
"name": "Northwind Retail",
"color": "#0ea5e9",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 1,
"tag_id": 5
}
}
]
}
],
"first_page_url": "http://localhost/api/organizations/1/domains?page=1",
"from": 1,
"last_page": 1,
"last_page_url": "http://localhost/api/organizations/1/domains?page=1",
"links": [
{
"url": null,
"label": "« Previous",
"page": null,
"active": false
},
{
"url": "http://localhost/api/organizations/1/domains?page=1",
"label": "1",
"page": 1,
"active": true
}
],
"next_page_url": null,
"path": "http://localhost/api/organizations/1/domains",
"per_page": 25,
"prev_page_url": null,
"to": 20,
"total": 20,
"meta": {
"locked_ids": [],
"expiry_window_days": 60,
"counts": {
"total": 20,
"active": 19,
"expiring_soon": 3,
"autorenew_off": 5,
"failed": 0,
"archived": 0
},
"integrations": [],
"tags": [
{
"id": 3,
"name": "Customer-facing",
"color": "#3b82f6"
},
{
"id": 4,
"name": "Internal",
"color": "#8b5cf6"
}
],
"uses": {
"sites": [
{
"key": "host:hetzner",
"label": "Hetzner",
"count": 12
},
{
"key": "none",
"label": null,
"count": 1
}
],
"mail": [
{
"key": "other",
"label": null,
"count": 7
},
{
"key": "none",
"label": null,
"count": 6
}
]
},
"custom_fields": [
{
"id": 1,
"key": "cost_centre",
"label": "Cost centre",
"type": "select",
"options": [
"Platform",
"Marketing"
]
}
]
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
List a domain’s running registrar actions
The action currently running at the registrar for this domain, where the registrar reports one; can_retry says whether it can be retried. An empty list when no registrar is linked or the registrar does not offer this.
/organizations/{organization}/domains/{domain}/actionsdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/actions" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/actions" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/actions', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/actions",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/actions', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/actions", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"actions": []
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Get a domain’s advisor findings
The current advisor findings for one domain, taking into account what its registrar supports.
/organizations/{organization}/domains/{domain}/advisordomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/advisor" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/advisor" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/advisor', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/advisor",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/advisor', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/advisor", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"expiry_window_days": 60,
"findings": [
{
"key": "expiry",
"check": "expiry",
"status": "info",
"variant": "renewalUnknown",
"params": {
"days": 18,
"expires_at": "2026-02-02",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"action": null,
"cause": "domain:1:expiry",
"rank": 222,
"home": {
"source": "domain_finding",
"key": "domain_finding:domain:1:expiry",
"fingerprint": ""
},
"snoozed": false
},
{
"key": "auto_renew",
"check": "auto_renew",
"status": "info",
"variant": "unknown",
"params": {
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"action": null,
"cause": "portfolio:auto_renew",
"rank": 150,
"home": {
"source": "domain_finding",
"key": "domain_finding:portfolio:auto_renew",
"fingerprint": ""
},
"snoozed": false
}
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Archive a domain
Takes the domain out of your working list while keeping it, its costs and its links; it keeps syncing and stops counting toward your plan’s domain limit. Refused with 422 while the domain is still active at a connected registrar.
/organizations/{organization}/domains/{domain}/archivedomains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/domains/1/archive" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/domains/1/archive" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/domains/1/archive', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/domains/1/archive",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/archive', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/domains/1/archive", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"name": "northwind",
"tld": "com",
"registrar": "Namecheap",
"registered_at": "2023-12-28T00:00:00.000000Z",
"expires_at": "2026-02-02T00:00:00.000000Z",
"auto_renew": true,
"status": "active",
"notes": null,
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"transfer_lock": true,
"whois_privacy": true,
"registrar_contacts": null,
"dnssec_entries": [
{
"key_tag": 62949,
"algorithm": 13,
"digest_type": 2,
"digest": "FBF66B8D019C1EEC1E1A0B5A9D3C2E7F4A8B60D5C93E71F2A6B8D04C7E19A35B"
}
],
"has_dnssec": true,
"renewal_price": "12.50",
"renewal_price_currency": "EUR",
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "manual",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": "2026-01-15T12:00:00.000000Z",
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": "signed",
"dnssec_checked_at": "2026-01-15T11:25:00.000000Z",
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"full_name": "northwind.com",
"archivable": true,
"dns_host": "cloudflare",
"management": "tracked",
"sync_halt": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"name": [
"The name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Get a domain’s registrar capabilities
Which registrar operations are available for this domain, given what its registrar and extension support, with a reason when something is unavailable.
/organizations/{organization}/domains/{domain}/capabilitiesdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/capabilities" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/capabilities" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/capabilities', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/capabilities",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/capabilities', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/capabilities", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"capabilities": {
"nameservers": false,
"contacts": false,
"dnssec": false,
"transfer_lock": false,
"whois_privacy": false,
"auto_renew": false,
"auto_renew_reenable": false,
"complete_domain_list": false,
"epp_code": false,
"register": false,
"transfer": false,
"renew": false
},
"reason": "no_registrar_credential",
"registry_withheld": [],
"contact_roles": [
"registrant",
"admin"
],
"dnssec_fields": [
"key_tag",
"flags"
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
List a domain’s contacts
The contacts assigned to the domain, each with its role in pivot.type.
/organizations/{organization}/domains/{domain}/contactsdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/contacts" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/contacts" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/contacts', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/contacts",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/contacts', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/contacts", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
[]{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Assign a contact to a domain
Assigns one of your contacts (contact_id) to the domain as registrant, admin, tech or billing, replacing whoever held that role. Recorded in InfraNest only; nothing is sent to the registrar.
/organizations/{organization}/domains/{domain}/contactsdomains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Bodyapplication/json
contact_idintegerrequiredtypestringrequiredOne of: registrant, admin, tech, billing
Request
curl -X POST "https://api.infranest.io/api/organizations/42/domains/1/contacts" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"contact_id":1,"type":"admin"}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"contact_id": 1,
"type": "admin"
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/domains/1/contacts" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/domains/1/contacts', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'contact_id' => 1,
'type' => 'admin',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/domains/1/contacts",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"contact_id": 1,
"type": "admin",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/contacts', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"contact_id": 1,
"type": "admin"
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/domains/1/contacts", strings.NewReader(`{"contact_id":1,"type":"admin"}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"first_name": "Alex",
"last_name": "Rivera",
"company": "Northwind Cloud",
"email": "domains@northwind.example",
"phone": "+31 20 555 0123",
"address": "Keizersgracht",
"city": "Amsterdam",
"state": null,
"zip": "1015 CJ",
"country": "NL",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"house_number": "123",
"vat_number": null,
"company_number": null,
"missing_for_registration": [],
"pivot": {
"type": "admin"
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The contact id field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"contact_id": [
"The contact id field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Remove a contact from a domain
Unassigns the contact from the domain in every role it held. The contact itself is kept.
/organizations/{organization}/domains/{domain}/contacts/{contact}domains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
contactintegerrequiredThe contact's ID.
Request
curl -X DELETE "https://api.infranest.io/api/organizations/42/domains/1/contacts/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Delete -Uri "https://api.infranest.io/api/organizations/42/domains/1/contacts/1" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.infranest.io/api/organizations/42/domains/1/contacts/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.delete(
"https://api.infranest.io/api/organizations/42/domains/1/contacts/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.status_code)const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/contacts/1', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("DELETE", "https://api.infranest.io/api/organizations/42/domains/1/contacts/1", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
No content.{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
429 rate_limited
Get a domain’s transfer code
Fetches the domain’s EPP (auth) code live from its registrar; InfraNest never stores it. Needs write access; answers 404 when no registrar is linked or the registrar cannot provide the code.
/organizations/{organization}/domains/{domain}/epp-codedomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/epp-code" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/epp-code" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/epp-code', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/epp-code",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/epp-code', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/epp-code", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
No success response is recorded for this endpoint yet.
Get a domain’s audit history
The 50 most recent audit-log entries for the domain and its manual cost items, newest first.
/organizations/{organization}/domains/{domain}/historydomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/history" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/history" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/history', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/history",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/history', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/history", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
[]{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Check a domain’s nameservers
Checks each of the domain’s nameservers now: whether it answers on port 53 and is authoritative, whether the nameservers agree with each other, and whether DNSSEC validates. Empty when the domain has no nameservers; the result is kept for the advisor.
/organizations/{organization}/domains/{domain}/ns-healthdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/ns-health" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/ns-health" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/ns-health', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/ns-health",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/ns-health', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/ns-health", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"checks": [
{
"ns": "nina.ns.cloudflare.com",
"authoritative": true,
"reachable": true
},
{
"ns": "rick.ns.cloudflare.com",
"authoritative": true,
"reachable": true
}
],
"ns_consistency": {
"consistent": true,
"resolvers": {
"cloudflare": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"google": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"dnssb": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"adguard": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"nextdns": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
]
}
},
"dnssec_validates": true,
"zone_delegation": {
"zone_id": 1,
"zone_name": "northwind.com",
"provider": "cloudflare",
"delegated": true,
"delegated_to": null
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Get a domain’s registrar pricing
The registrar’s current prices for the domain’s extension, asked live. Answers 404 when no registrar connection is linked; pricing is null when the registrar does not allow price lookups with your key.
/organizations/{organization}/domains/{domain}/pricingdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/pricing" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/pricing" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/pricing', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/pricing",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/pricing', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/pricing", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
No success response is recorded for this endpoint yet.
Get a domain’s registry record
What the registry itself says about the domain: its status codes, created and updated dates, the source (RDAP or WHOIS) and an excerpt of the raw answer.
/organizations/{organization}/domains/{domain}/registry-recorddomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/registry-record" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/registry-record" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/registry-record', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/registry-record",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/registry-record', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/registry-record", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"statuses": [],
"created_at": null,
"updated_at": null,
"source": null,
"raw": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Get how a domain is set up
Who hosts the domain’s DNS and whether its nameservers answer, its mail provider, and the servers, certificates, monitors and status pages behind its addresses. Based on the DNS zone InfraNest holds; a domain whose DNS is hosted elsewhere gets no website or email details.
/organizations/{organization}/domains/{domain}/setupdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/setup" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/setup" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/setup', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/setup",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/setup', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/setup", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"zone": {
"id": 1,
"name": "northwind.com"
},
"registrar": {
"label": "Namecheap",
"managed": false,
"credential_id": null,
"provider": null
},
"dns": {
"provider": "cloudflare",
"provider_label": "Cloudflare",
"connected": true,
"zone_here": true,
"nameservers": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"answering": null,
"checked_at": null
},
"email": {
"provider": null,
"hosts": [
"mx.northwind.com"
]
},
"website": {
"records": [
{
"type": "A",
"value": "198.51.100.10",
"url": "/dns/1?record=1"
}
],
"server": {
"type": "server",
"id": 1,
"label": "web-01",
"sublabel": "198.51.100.10",
"url": "/servers/1",
"meta": []
}
},
"runs_on": [
{
"record_id": 1,
"zone_id": 1,
"host": "northwind.com",
"type": "A",
"value": "198.51.100.10",
"url": "/dns/1?record=1",
"server": {
"type": "server",
"id": 1,
"label": "web-01",
"sublabel": "198.51.100.10",
"url": "/servers/1",
"meta": []
},
"certificate": {
"type": "certificate",
"id": 1,
"label": "northwind.com",
"sublabel": "2026-03-30",
"url": "/certificates/1",
"meta": []
},
"monitors": [
{
"type": "monitor",
"id": 1,
"label": "Marketing site",
"sublabel": "https://northwind.com",
"url": "/monitoring/1",
"meta": {
"type": "http",
"last_status": "up",
"last_checked_at": "2026-01-15T11:58:00.000000Z"
}
},
{
"type": "monitor",
"id": 4,
"label": "Checkout flow",
"sublabel": "https://northwind.com/checkout",
"url": "/monitoring/4",
"meta": {
"type": "http",
"last_status": "down",
"last_checked_at": "2026-01-15T11:58:00.000000Z"
}
}
],
"status_pages": []
},
{
"record_id": 3,
"zone_id": 1,
"host": "api.northwind.com",
"type": "CNAME",
"value": "northwind.com",
"url": "/dns/1?record=3",
"server": null,
"certificate": {
"type": "certificate",
"id": 3,
"label": "api.northwind.com",
"sublabel": "2026-04-13",
"url": "/certificates/3",
"meta": []
},
"monitors": [
{
"type": "monitor",
"id": 3,
"label": "API health",
"sublabel": "https://api.northwind.com/health",
"url": "/monitoring/3",
"meta": {
"type": "http",
"last_status": "up",
"last_checked_at": "2026-01-15T11:58:00.000000Z"
}
},
{
"type": "monitor",
"id": 6,
"label": "Search API",
"sublabel": "https://api.northwind.com/v1/search",
"url": "/monitoring/6",
"meta": {
"type": "api",
"last_status": "degraded",
"last_checked_at": "2026-01-15T11:58:00.000000Z"
}
}
],
"status_pages": []
}
],
"mail": [
{
"record_id": 4,
"value": "mx.northwind.com",
"url": "/dns/1?record=4"
}
],
"unmonitored": [
"archive.northwind.com",
"cdn.northwind.com"
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Unarchive a domain
Brings an archived domain back into your working list, where it counts toward your plan’s domain limit again. A domain that is not archived is returned unchanged.
/organizations/{organization}/domains/{domain}/unarchivedomains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/domains/1/unarchive" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/domains/1/unarchive" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/domains/1/unarchive', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/domains/1/unarchive",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/unarchive', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/domains/1/unarchive", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"name": "northwind",
"tld": "com",
"registrar": "Namecheap",
"registered_at": "2023-12-28T00:00:00.000000Z",
"expires_at": "2026-02-02T00:00:00.000000Z",
"auto_renew": true,
"status": "active",
"notes": null,
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"transfer_lock": true,
"whois_privacy": true,
"registrar_contacts": null,
"dnssec_entries": [
{
"key_tag": 62949,
"algorithm": 13,
"digest_type": 2,
"digest": "FBF66B8D019C1EEC1E1A0B5A9D3C2E7F4A8B60D5C93E71F2A6B8D04C7E19A35B"
}
],
"has_dnssec": true,
"renewal_price": "12.50",
"renewal_price_currency": "EUR",
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "manual",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": null,
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": "signed",
"dnssec_checked_at": "2026-01-15T11:25:00.000000Z",
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"full_name": "northwind.com",
"archivable": true,
"dns_host": "cloudflare",
"management": "tracked",
"sync_halt": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"name": [
"The name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Look up a domain’s WHOIS
A live WHOIS lookup for the domain. Answers 422 with a message when the lookup fails.
/organizations/{organization}/domains/{domain}/whoisdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
domainintegerrequiredThe domain's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1/whois" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1/whois" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1/whois', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1/whois",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1/whois', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1/whois", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"server": "whois.verisign-grs.com",
"output": " Domain Name: NORTHWIND.COM\r\n Registry Domain ID: 4516866_DOMAIN_COM-VRSN\r\n Registrar WHOIS Server: whois.godaddy.…"
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Get a domain
One domain with its full details. A domain over your plan’s domain limit is locked and cannot be opened; stale renewal pricing is refreshed in the background.
/organizations/{organization}/domains/{id}domains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
idintegerrequiredThe id's ID.
Request
curl "https://api.infranest.io/api/organizations/42/domains/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/1" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/1", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"name": "northwind",
"tld": "com",
"registrar": "Namecheap",
"registered_at": "2023-12-28T00:00:00.000000Z",
"expires_at": "2026-02-02T00:00:00.000000Z",
"auto_renew": true,
"status": "active",
"notes": null,
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"transfer_lock": true,
"whois_privacy": true,
"registrar_contacts": null,
"dnssec_entries": [
{
"key_tag": 62949,
"algorithm": 13,
"digest_type": 2,
"digest": "FBF66B8D019C1EEC1E1A0B5A9D3C2E7F4A8B60D5C93E71F2A6B8D04C7E19A35B"
}
],
"has_dnssec": true,
"renewal_price": "12.50",
"renewal_price_currency": "EUR",
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "manual",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": null,
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": "signed",
"dnssec_checked_at": "2026-01-15T11:25:00.000000Z",
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"full_name": "northwind.com",
"archivable": true,
"dns_host": "cloudflare",
"management": "tracked",
"sync_halt": null,
"contacts": [],
"provider_credential": null,
"tags": [
{
"id": 3,
"name": "Customer-facing",
"color": "#3b82f6",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 1,
"tag_id": 3
}
},
{
"id": 5,
"name": "Northwind Retail",
"color": "#0ea5e9",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 1,
"tag_id": 5
}
}
],
"dns_zone": {
"id": 1,
"name": "northwind.com",
"provider": "cloudflare",
"provider_label": "Cloudflare",
"points_here": true,
"can_sign": true
},
"tracked": {
"registrar": "Namecheap",
"provider": {
"key": "namecheap",
"label": "Namecheap",
"integrable": true
},
"connected": true,
"checked_at": null
},
"capabilities": {
"nameservers": false,
"contacts": false,
"dnssec": false,
"transfer_lock": false,
"whois_privacy": false,
"auto_renew": false,
"auto_renew_reenable": false,
"complete_domain_list": false,
"epp_code": false,
"register": false,
"transfer": false,
"renew": false
},
"capabilities_reason": "no_registrar_credential",
"registry_withheld": [],
"contact_roles": [
"registrant",
"admin"
],
"settings": {
"transfer_lock": {
"state": "on",
"source": "registry",
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"auto_renew": {
"state": "unknown",
"source": null,
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"whois_privacy": {
"state": "on",
"source": "registrar",
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"dnssec": {
"state": "unknown",
"source": null,
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"caa": {
"state": "off",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"spf": {
"state": "on",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"dmarc": {
"state": "on",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"email": {
"state": "on",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"dkim": {
"state": "off",
"source": "zone",
"route": "elsewhere",
"where": null
},
"no_mail": {
"state": "none",
"source": null,
"route": null,
"where": null
}
},
"advisor": {
"expiry_window_days": 60,
"findings": [
{
"key": "expiry",
"check": "expiry",
"status": "info",
"variant": "renewalUnknown",
"params": {
"days": 18,
"expires_at": "2026-02-02",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"action": null,
"cause": "domain:1:expiry",
"rank": 222,
"home": {
"source": "domain_finding",
"key": "domain_finding:domain:1:expiry",
"fingerprint": ""
},
"snoozed": false
},
{
"key": "auto_renew",
"check": "auto_renew",
"status": "info",
"variant": "unknown",
"params": {
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"action": null,
"cause": "portfolio:auto_renew",
"rank": 150,
"home": {
"source": "domain_finding",
"key": "domain_finding:portfolio:auto_renew",
"fingerprint": ""
},
"snoozed": false
}
]
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Update a domain
Updates what InfraNest keeps for the domain: notes, serves_website, expected_issuers, nameservers, registrar_contacts, pricing and tag_ids. Registration data such as the expiry date and auto-renew is not accepted here; returns the domain’s full details.
/organizations/{organization}/domains/{id}domains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
idintegerrequiredThe id's ID.
Bodyapplication/json
notesstring, nullableoptionalMust not be greater than 10000 characters.
tag_idsarrayoptionalserves_websiteboolean, nullableoptionalexpected_issuersarrayoptionalMust not be greater than 100 characters.
nameserversarrayoptionalMust not be greater than 253 characters.
registrar_contactsobject, nullableoptionalrenewal_pricenumber, nullableoptionalMust be at least 0. Must not be greater than 9999999.99.
renewal_price_currencystring, nullableoptionalMust be 3 characters.
billing_intervalstringoptionalOne of: hourly, daily, weekly, monthly, quarterly, yearly
interval_countintegeroptionalMust be at least 1. Must not be greater than 120.
purchase_pricenumber, nullableoptionalMust be at least 0. Must not be greater than 9999999.99.
purchase_price_currencystring, nullableoptionalMust be 3 characters.
Request
curl -X PUT "https://api.infranest.io/api/organizations/42/domains/1" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"notes":"Main brand domain. Renew three years ahead."}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"notes": "Main brand domain. Renew three years ahead."
}
'@
Invoke-RestMethod -Method Put -Uri "https://api.infranest.io/api/organizations/42/domains/1" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api.infranest.io/api/organizations/42/domains/1', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'notes' => 'Main brand domain. Renew three years ahead.',
],
]);
echo $response->getBody();import os
import requests
response = requests.put(
"https://api.infranest.io/api/organizations/42/domains/1",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"notes": "Main brand domain. Renew three years ahead.",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/1', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"notes": "Main brand domain. Renew three years ahead."
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("PUT", "https://api.infranest.io/api/organizations/42/domains/1", strings.NewReader(`{"notes":"Main brand domain. Renew three years ahead."}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 1,
"organization_id": 1,
"name": "northwind",
"tld": "com",
"registrar": "Namecheap",
"registered_at": "2023-12-28T00:00:00.000000Z",
"expires_at": "2026-02-02T00:00:00.000000Z",
"auto_renew": true,
"status": "active",
"notes": "Main brand domain. Renew three years ahead.",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": [
"nina.ns.cloudflare.com",
"rick.ns.cloudflare.com"
],
"transfer_lock": true,
"whois_privacy": true,
"registrar_contacts": null,
"dnssec_entries": [
{
"key_tag": 62949,
"algorithm": 13,
"digest_type": 2,
"digest": "FBF66B8D019C1EEC1E1A0B5A9D3C2E7F4A8B60D5C93E71F2A6B8D04C7E19A35B"
}
],
"has_dnssec": true,
"renewal_price": "12.50",
"renewal_price_currency": "EUR",
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "manual",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": null,
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": "signed",
"dnssec_checked_at": "2026-01-15T11:25:00.000000Z",
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"full_name": "northwind.com",
"archivable": true,
"dns_host": "cloudflare",
"management": "tracked",
"sync_halt": null,
"contacts": [
{
"id": 1,
"organization_id": 1,
"first_name": "Alex",
"last_name": "Rivera",
"company": "Northwind Cloud",
"email": "domains@northwind.example",
"phone": "+31 20 555 0123",
"address": "Keizersgracht",
"city": "Amsterdam",
"state": null,
"zip": "1015 CJ",
"country": "NL",
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"house_number": "123",
"vat_number": null,
"company_number": null,
"missing_for_registration": [],
"pivot": {
"domain_id": 1,
"contact_id": 1,
"type": "tech",
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z"
}
}
],
"provider_credential": null,
"tags": [
{
"id": 3,
"name": "Customer-facing",
"color": "#3b82f6",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 1,
"tag_id": 3
}
},
{
"id": 5,
"name": "Northwind Retail",
"color": "#0ea5e9",
"pivot": {
"taggable_type": "App\\Models\\Domain",
"taggable_id": 1,
"tag_id": 5
}
}
],
"dns_zone": {
"id": 1,
"name": "northwind.com",
"provider": "cloudflare",
"provider_label": "Cloudflare",
"points_here": true,
"can_sign": true
},
"tracked": {
"registrar": "Namecheap",
"provider": {
"key": "namecheap",
"label": "Namecheap",
"integrable": true
},
"connected": true,
"checked_at": null
},
"capabilities": {
"nameservers": false,
"contacts": false,
"dnssec": false,
"transfer_lock": false,
"whois_privacy": false,
"auto_renew": false,
"auto_renew_reenable": false,
"complete_domain_list": false,
"epp_code": false,
"register": false,
"transfer": false,
"renew": false
},
"capabilities_reason": "no_registrar_credential",
"registry_withheld": [],
"contact_roles": [
"registrant",
"admin"
],
"settings": {
"transfer_lock": {
"state": "on",
"source": "registry",
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"auto_renew": {
"state": "unknown",
"source": null,
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"whois_privacy": {
"state": "on",
"source": "registrar",
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"dnssec": {
"state": "unknown",
"source": null,
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"caa": {
"state": "off",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"spf": {
"state": "on",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"dmarc": {
"state": "on",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"email": {
"state": "on",
"source": "zone",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
}
},
"dkim": {
"state": "off",
"source": "zone",
"route": "elsewhere",
"where": null
},
"no_mail": {
"state": "none",
"source": null,
"route": null,
"where": null
}
},
"advisor": {
"expiry_window_days": 60,
"findings": [
{
"key": "expiry",
"check": "expiry",
"status": "info",
"variant": "renewalUnknown",
"params": {
"days": 18,
"expires_at": "2026-02-02",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"action": null,
"cause": "domain:1:expiry",
"rank": 222,
"home": {
"source": "domain_finding",
"key": "domain_finding:domain:1:expiry",
"fingerprint": ""
},
"snoozed": false
},
{
"key": "auto_renew",
"check": "auto_renew",
"status": "info",
"variant": "unknown",
"params": {
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
}
},
"action": null,
"cause": "portfolio:auto_renew",
"rank": 150,
"home": {
"source": "domain_finding",
"key": "domain_finding:portfolio:auto_renew",
"fingerprint": ""
},
"snoozed": false
}
]
}
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The notes field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"notes": [
"The notes field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
422 validation_failed
429 rate_limited
Plan CAA protection across domains
For each domain in ids (up to 200), the CAA plan and its route, as for the email protection plan. Changes nothing; apply it through each zone’s CAA protection endpoint, which checks the zone’s certificates first.
/organizations/{organization}/domains/caa-protection-plandomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Query parameters
idsarrayoptionalRequest
curl "https://api.infranest.io/api/organizations/42/domains/caa-protection-plan" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/caa-protection-plan" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/caa-protection-plan', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/caa-protection-plan",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/caa-protection-plan', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/caa-protection-plan", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"domains": [
{
"id": 1,
"name": "northwind.com",
"zone_id": 1,
"route": "here",
"plan": {
"zone_id": 1,
"zone": "northwind.com",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
},
"records": [
{
"key": "kept:7",
"action": "none",
"type": "CAA",
"name": "@",
"value": "0 issue \"letsencrypt.org\"",
"current": null,
"record_id": null,
"reason": "caa_kept",
"params": []
},
{
"key": "issue:globalsign.com",
"action": "create",
"type": "CAA",
"name": "@",
"value": "0 issue \"globalsign.com\"",
"current": null,
"record_id": null,
"reason": "caa_cert",
"params": {
"subject": "shop.northwind.com"
}
}
],
"refusals": [],
"certificates": [
{
"id": 1,
"subject": "northwind.com",
"issuer": "Let's Encrypt (R3)",
"ca": "letsencrypt.org",
"wildcard": false,
"state": "stays_renewable"
},
{
"id": 13,
"subject": "cdn.northwind.com",
"issuer": "Let's Encrypt (R3)",
"ca": "letsencrypt.org",
"wildcard": false,
"state": "stays_renewable"
}
],
"fronts": [
{
"label": "Cloudflare",
"ids": [
"letsencrypt.org",
"pki.goog"
],
"publishes_own": true
}
]
}
}
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Plan email protection across domains
For each domain in ids (up to 200), the email protection plan for mode (protect or no_mail) and its route: here, elsewhere (records to copy to your DNS host), reconnect, unchanged, refused or none (no zone held). Changes nothing; apply it through each zone’s email protection endpoint.
/organizations/{organization}/domains/email-protection-plandomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Query parameters
modestringrequiredidsarrayoptionalRequest
curl "https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"mode": "no_mail",
"domains": [
{
"id": 1,
"name": "northwind.com",
"zone_id": 1,
"route": "refused",
"plan": {
"zone_id": 1,
"zone": "northwind.com",
"mode": "no_mail",
"route": "here",
"where": {
"label": "Cloudflare",
"url": null
},
"provider": null,
"providers": [],
"records": [],
"refusals": [
{
"key": "mode",
"reason": "receives_mail",
"params": []
}
],
"lookups": null,
"dkim": null
}
}
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Get the domains overview
A summary of your domains: what needs your attention, what the next year of renewals costs in your base currency, and how the portfolio is protected.
/organizations/{organization}/domains/overviewdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/domains/overview" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/overview" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/overview', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/overview",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/overview', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/overview", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"summary": {
"total": 20,
"fine": 16,
"need_you": 4,
"this_week": 2,
"registrars": 7,
"renewal_cost": 327.5,
"currency": "EUR",
"auto_renewing": 0,
"synced_at": null,
"next_renewal": {
"domain_id": 14,
"name": "northwind-labs.com",
"expires_at": "2026-01-24",
"auto_renew": false
}
},
"needs_you": [
{
"key": "expiry",
"check": "expiry",
"status": "error",
"variant": "lapsed",
"params": {
"days": -6,
"expires_at": "2026-01-09"
},
"action": "renew",
"cause": "domain:18:expiry",
"rank": 390,
"home": {
"source": "domain_expiring",
"key": "domain:18",
"fingerprint": "2026-01-09"
},
"snoozed": false,
"domains": [
{
"id": 18,
"name": "nwcloud.app"
}
],
"attention_keys": [
"domain:18"
],
"due_in_days": 0,
"renewal": null,
"evidence": [
{
"source": "registrar",
"state": "auto_renew_off",
"tone": "bad"
}
],
"prevention": {
"template": "auto_renew_expiring_domains",
"active": false
}
},
{
"key": "dnssec",
"check": "dnssec",
"status": "error",
"variant": "notValidating",
"params": {
"since": "2026-01-13T12:00:00.000000Z"
},
"action": null,
"cause": "domain:9:dnssec",
"rank": 350,
"home": {
"source": "dnssec_broken",
"key": "dnssec_broken:9",
"fingerprint": ""
},
"snoozed": false,
"domains": [
{
"id": 9,
"name": "northwind.de"
}
],
"attention_keys": [
"dnssec_broken:9"
],
"due_in_days": 0,
"renewal": null,
"evidence": [],
"prevention": null
}
],
"decided": [],
"renewals": {
"currency": "EUR",
"priced": true,
"total": 327.5,
"items": 18,
"unpriced": 0,
"months": [
{
"month": "2026-01",
"cost": 44.5,
"items": 2,
"unpriced": 0,
"decide_cost": 44.5,
"decide_items": 2,
"domains": [
{
"id": 10,
"name": "northwind.shop",
"cost": 32,
"decide": true
},
{
"id": 14,
"name": "northwind-labs.com",
"cost": 12.5,
"decide": true
}
],
"more": 0
},
{
"month": "2026-02",
"cost": 12.5,
"items": 1,
"unpriced": 0,
"decide_cost": 12.5,
"decide_items": 1,
"domains": [
{
"id": 1,
"name": "northwind.com",
"cost": 12.5,
"decide": true
}
],
"more": 0
}
],
"savings": {
"unused": [],
"total": 0
}
},
"protection": [
{
"setting": "transfer_lock",
"on": 14,
"applicable": 16,
"off": [
14,
18
],
"applies": true,
"here": [],
"reconnect": [],
"elsewhere": [
{
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/",
"ids": [
14,
18
]
}
],
"unknown": 0,
"none": 3
},
{
"setting": "auto_renew",
"on": 0,
"applicable": 5,
"off": [
4,
10
],
"applies": true,
"here": [],
"reconnect": [],
"elsewhere": [
{
"label": "Cloudflare",
"url": "https://dash.cloudflare.com/?to=/:account/domains",
"ids": [
4
]
},
{
"label": "Porkbun",
"url": "https://porkbun.com/account/domainsSpeedy",
"ids": [
10
]
}
],
"unknown": 14,
"none": 0
}
],
"stale": [],
"found_elsewhere": [],
"cheaper_registrar": {
"groups": [],
"set_aside": []
},
"setup": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
List registrar moves
The 200 most recent moves of domains to another registrar you have connected, newest first, each with its domain, source and target connection, and current state.
/organizations/{organization}/domains/registrar-movesdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Request
curl "https://api.infranest.io/api/organizations/42/domains/registrar-moves" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/registrar-moves" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/registrar-moves', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/registrar-moves",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/registrar-moves', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/registrar-moves", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"data": []
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Get registration requirements for an extension
The extra fields a registrar needs to register a domain under tld (for example the nexus details some country extensions ask for) and the registration periods it offers. credential_id and tld are required; unknown is true when the registrar could not be asked, in which case it may still refuse.
/organizations/{organization}/domains/registration-fieldsdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Query parameters
credential_idintegerrequiredMust match an existing stored value.
tldstringoptionalRequest
curl "https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"fields": [],
"unknown": true,
"periods": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Plan a settings change across domains
For each domain in ids (up to 500), who would carry out turning setting on or off (value, default true). Changes nothing; each setting is changed through its own endpoint.
/organizations/{organization}/domains/settings-plandomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Query parameters
settingstringrequiredvaluebooleanoptionalidsarrayoptionalRequest
curl "https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"setting": "auto_renew",
"value": true,
"applies": true,
"domains": [
{
"id": 1,
"name": "northwind.com",
"state": "unknown",
"route": "elsewhere",
"where": {
"label": "Namecheap",
"url": "https://ap.www.namecheap.com/domains/list/"
},
"dnssec": null,
"zone_id": null
}
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited
Track a domain by name
Adds a domain held at a registrar InfraNest is not connected to; its registrar, dates, status and nameservers are read from the public registry, now and daily. Only name is accepted; it counts toward your plan’s domain limit, and a domain already in your organization is refused with 422.
/organizations/{organization}/domains/trackdomains.writeChanges dataAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Bodyapplication/json
namestringrequiredMust not be greater than 253 characters.
Request
curl -X POST "https://api.infranest.io/api/organizations/42/domains/track" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name":"northwind-studio.com"}'$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
$body = @'
{
"name": "northwind-studio.com"
}
'@
Invoke-RestMethod -Method Post -Uri "https://api.infranest.io/api/organizations/42/domains/track" -Headers $headers -ContentType "application/json" -Body $body<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.infranest.io/api/organizations/42/domains/track', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
'json' => [
'name' => 'northwind-studio.com',
],
]);
echo $response->getBody();import os
import requests
response = requests.post(
"https://api.infranest.io/api/organizations/42/domains/track",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
json={
"name": "northwind-studio.com",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/track', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "northwind-studio.com"
}),
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
req, err := http.NewRequest("POST", "https://api.infranest.io/api/organizations/42/domains/track", strings.NewReader(`{"name":"northwind-studio.com"}`))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"id": 21,
"organization_id": 1,
"name": "northwind-studio",
"tld": "com",
"registrar": null,
"registered_at": null,
"expires_at": null,
"auto_renew": true,
"status": "active",
"notes": null,
"deleted_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"provider_credential_id": null,
"nameservers": null,
"transfer_lock": null,
"whois_privacy": null,
"registrar_contacts": null,
"dnssec_entries": null,
"has_dnssec": null,
"renewal_price": null,
"renewal_price_currency": null,
"pricing_cached_at": null,
"last_details_synced_at": null,
"status_message": null,
"expected_issuers": null,
"renewal_price_source": "api",
"purchase_price": null,
"purchase_price_currency": null,
"registrar_price": null,
"registrar_price_currency": null,
"registrar_flags": null,
"requested_whois_privacy": null,
"requested_auto_renew": null,
"archived_at": null,
"requested_nameservers": null,
"missing_since": null,
"serves_website": null,
"billing_interval": "yearly",
"interval_count": 1,
"dnssec_state": null,
"dnssec_checked_at": null,
"dnssec_broken_since": null,
"requested_dns_credential_id": null,
"requested_dns_template": null,
"status_detail": null,
"ordered_by_user_id": null,
"ns_health": null,
"ns_health_checked_at": null,
"unused_since": null,
"registry_statuses": null,
"registry_checked_at": null,
"registry_dnssec": null,
"full_name": "northwind-studio.com",
"archivable": true,
"dns_host": null,
"management": "tracked",
"sync_halt": null
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.write scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.write",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "idempotency_in_progress",
"message": "A request with this Idempotency-Key is still being handled.",
"hint": "Wait a few seconds, then send the same request with the same key again to get its result.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#idempotency_in_progress",
"reference": "k3j9x0b2qa"
}{
"code": "validation_failed",
"message": "The name field is required.",
"hint": "Fix the fields listed in \"errors\" and send the request again.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#validation_failed",
"errors": {
"name": [
"The name field is required."
]
},
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied write_disabled organization_suspended
404 not_found
409 idempotency_in_progress
422 validation_failed idempotency_key_reused
429 rate_limited
Check a domain before transferring it in
Checks the usual reasons an inbound transfer fails for the domain given by name and tld, before you submit it. Optionally pass credential_id for the registrar that would receive it; counts toward your plan’s hourly domain-check limit.
/organizations/{organization}/domains/transfer-preflightdomains.readRead onlyAuthorizationheader
AuthorizationstringrequiredBearer and your API token: Bearer $INFRANEST_TOKEN. See Tokens and scopes.
Path parameters
organizationintegerrequiredYour organization's ID: the number after /organizations/ in the app's address, or from GET /organizations.
Query parameters
namestringrequiredMust not be greater than 100 characters.
tldstringrequiredMust not be greater than 30 characters.
credential_idinteger, nullableoptionalWhich of the org's registrars the transfer would go to. Optional: the registry checks below are about the losing side and run without it. Scoped to the org rather than taken on trust — a credential id from another tenant would otherwise make one API call on their key.
Request
curl "https://api.infranest.io/api/organizations/42/domains/transfer-preflight?name=www&tld=%3Ctld%3E" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"$headers = @{
Authorization = "Bearer $env:INFRANEST_TOKEN"
Accept = "application/json"
}
Invoke-RestMethod -Method Get -Uri "https://api.infranest.io/api/organizations/42/domains/transfer-preflight?name=www&tld=%3Ctld%3E" -Headers $headers<?php
// composer require guzzlehttp/guzzle
require "vendor/autoload.php";
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.infranest.io/api/organizations/42/domains/transfer-preflight?name=www&tld=%3Ctld%3E', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('INFRANEST_TOKEN'),
'Accept' => 'application/json',
],
]);
echo $response->getBody();import os
import requests
response = requests.get(
"https://api.infranest.io/api/organizations/42/domains/transfer-preflight?name=www&tld=%3Ctld%3E",
headers={
"Authorization": f"Bearer {os.environ['INFRANEST_TOKEN']}",
"Accept": "application/json",
},
)
response.raise_for_status()
print(response.json())const response = await fetch('https://api.infranest.io/api/organizations/42/domains/transfer-preflight?name=www&tld=%3Ctld%3E', {
headers: {
Authorization: `Bearer ${process.env.INFRANEST_TOKEN}`,
Accept: 'application/json',
},
})
console.log(response.status, await response.text())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://api.infranest.io/api/organizations/42/domains/transfer-preflight?name=www&tld=%3Ctld%3E", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRANEST_TOKEN"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}Response
{
"domain": "northwind.com",
"registrar": "Namecheap",
"expires_at": "2026-02-02",
"source": "fixture",
"checks": [
{
"key": "not_locked",
"status": "warn",
"detail": []
},
{
"key": "sixty_day_rule",
"status": "pass",
"detail": {
"days": 749,
"free_on": "2024-02-26",
"since": "registration"
}
}
]
}{
"code": "unauthenticated",
"message": "You are not signed in, or the API token is missing, wrong, expired or revoked.",
"hint": "Send a valid token in the Authorization header, as the word Bearer followed by the token. Create a new one under My account → Developer if it expired or was revoked.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#unauthenticated",
"reference": "k3j9x0b2qa"
}{
"code": "scope_missing",
"message": "This API token does not have the domains.read scope.",
"hint": "Create a token that includes the scope named in \"required\". Give each token only the scopes it needs.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#scope_missing",
"required": "domains.read",
"reference": "k3j9x0b2qa"
}{
"code": "not_found",
"message": "Nothing exists at this address, or you cannot see it.",
"hint": "Check the IDs in the address. A resource in another organization answers as not found.",
"retryable": false,
"docs_url": "https://developers.infranest.io/errors#not_found",
"reference": "k3j9x0b2qa"
}{
"code": "rate_limited",
"message": "This token made more than 300 requests in a minute.",
"hint": "Wait the number of seconds in \"retry_after\" (also the Retry-After header), then retry.",
"retryable": true,
"docs_url": "https://developers.infranest.io/errors#rate_limited",
"limit_key": "api_requests_per_minute",
"limit": 300,
"retry_after": 12,
"reference": "k3j9x0b2qa"
}401 unauthenticated
403 scope_missing wrong_organization test_token_required test_token_sandbox_only permission_denied
404 not_found
429 rate_limited