# Domains Domains and contacts as InfraNest knows them. Registrar actions (register, renew, transfer) stay in the app. **Common tasks** - [List your domains](#get-organizations-organization-domains) - [Start tracking a domain by name](#post-organizations-organization-domains-track) - [Keep the contact book up to date](#post-organizations-organization-contacts) **Only in the app:** Registering, renewing and transferring domains, nameservers and registrar settings. **How it works in the app:** [help article](https://infranest.io/docs/domains). **Scopes:** Read with `domains.read`, change with `domains.write`. See [Tokens and scopes](../tokens-and-scopes.md#scopes).
[Contacts](#contacts) 5 · [Domain findings](#domain-findings) 1 · [Domains](#domains) 26
Every endpoint below takes a token in the `Authorization: Bearer` header and answers JSON. Errors use the shared format in [Errors](../errors.md). Base address: `https://api.infranest.io/api`. ## Contacts ### List contacts {#get-organizations-organization-contacts}
`GET` `/organizations/{organization}/contacts` **Scope:** `domains.read` · **Changes data:** no 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`. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/contacts" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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": [] } } ```
--- ### Create a contact {#post-organizations-organization-contacts}
`POST` `/organizations/{organization}/contacts` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization Creates a contact you can assign to domains as registrant, admin, tech or billing contact, optionally tagged with `tag_ids`. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `first_name`
body · required | string | Must not be greater than 100 characters. | | `last_name`
body · required | string | Must not be greater than 100 characters. | | `company`
body | string, nullable | Must not be greater than 255 characters. | | `vat_number`
body | string, nullable | Must not be greater than 50 characters. | | `company_number`
body | string, nullable | Must not be greater than 50 characters. | | `email`
body · required | string | Must be a valid email address. Must not be greater than 255 characters. | | `phone`
body | string, nullable | Must not be greater than 50 characters. | | `address`
body | string, nullable | Must not be greater than 255 characters. | | `house_number`
body | string, nullable | Must not be greater than 20 characters. | | `city`
body | string, nullable | Must not be greater than 100 characters. | | `state`
body | string, nullable | Must not be greater than 100 characters. | | `zip`
body | string, nullable | Must not be greater than 20 characters. | | `country`
body · required | string | Must be 2 characters. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh 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"}' ``` **Response** · 201 — Created ```json { "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": [] } ```
--- ### Get a contact {#get-organizations-organization-contacts-id}
`GET` `/organizations/{organization}/contacts/{id}` **Scope:** `domains.read` · **Changes data:** no One contact with the domains it is assigned to. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `id`
path · required | integer | The id's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/contacts/1" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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": [] } ```
--- ### Update a contact {#put-organizations-organization-contacts-id}
`PUT` `/organizations/{organization}/contacts/{id}` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization Updates the contact and, when `tag_ids` is sent, its tags. Recorded in InfraNest only; nothing is sent to a registrar. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `id`
path · required | integer | The id's ID. | | `first_name`
body | string | Must not be greater than 100 characters. | | `last_name`
body | string | Must not be greater than 100 characters. | | `company`
body | string, nullable | Must not be greater than 255 characters. | | `vat_number`
body | string, nullable | Must not be greater than 50 characters. | | `company_number`
body | string, nullable | Must not be greater than 50 characters. | | `email`
body | string | Must be a valid email address. Must not be greater than 255 characters. | | `phone`
body | string, nullable | Must not be greater than 50 characters. | | `address`
body | string, nullable | Must not be greater than 255 characters. | | `house_number`
body | string, nullable | Must not be greater than 20 characters. | | `city`
body | string, nullable | Must not be greater than 100 characters. | | `state`
body | string, nullable | Must not be greater than 100 characters. | | `zip`
body | string, nullable | Must not be greater than 20 characters. | | `country`
body | string | Must be 2 characters. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`validation_failed`](../errors.md#validation_failed), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh 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"}' ``` **Response** · 200 ```json { "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": [] } ```
--- ### Delete a contact {#delete-organizations-organization-contacts-id}
`DELETE` `/organizations/{organization}/contacts/{id}` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization Deletes the contact from your organization. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `id`
path · required | integer | The id's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X DELETE "https://api.infranest.io/api/organizations/42/contacts/1" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 204 — no content
## Domain findings ### List domain findings {#get-organizations-organization-domain-findings}
`GET` `/organizations/{organization}/domain-findings` **Scope:** `domains.read` · **Changes data:** no Advisor findings across all your domains, most urgent first, with one finding per cause naming every domain it affects. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domain-findings" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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" } ] } ] } ```
## Domains ### List domains {#get-organizations-organization-domains}
`GET` `/organizations/{organization}/domains` **Scope:** `domains.read` · **Changes data:** no 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`. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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" ] } ] } } ```
--- ### List a domain’s running registrar actions {#get-organizations-organization-domains-domain-actions}
`GET` `/organizations/{organization}/domains/{domain}/actions` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/actions" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "actions": [] } ```
--- ### Get a domain’s advisor findings {#get-organizations-organization-domains-domain-advisor}
`GET` `/organizations/{organization}/domains/{domain}/advisor` **Scope:** `domains.read` · **Changes data:** no The current advisor findings for one domain, taking into account what its registrar supports. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/advisor" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ] } ```
--- ### Archive a domain {#post-organizations-organization-domains-domain-archive}
`POST` `/organizations/{organization}/domains/{domain}/archive` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X POST "https://api.infranest.io/api/organizations/42/domains/1/archive" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ```
--- ### Get a domain’s registrar capabilities {#get-organizations-organization-domains-domain-capabilities}
`GET` `/organizations/{organization}/domains/{domain}/capabilities` **Scope:** `domains.read` · **Changes data:** no Which registrar operations are available for this domain, given what its registrar and extension support, with a `reason` when something is unavailable. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/capabilities" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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" ] } ```
--- ### List a domain’s contacts {#get-organizations-organization-domains-domain-contacts}
`GET` `/organizations/{organization}/domains/{domain}/contacts` **Scope:** `domains.read` · **Changes data:** no The contacts assigned to the domain, each with its role in `pivot.type`. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/contacts" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json [] ```
--- ### Assign a contact to a domain {#post-organizations-organization-domains-domain-contacts}
`POST` `/organizations/{organization}/domains/{domain}/contacts` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | | `contact_id`
body · required | integer | | | `type`
body · required | string | One of: `registrant`, `admin`, `tech`, `billing`. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh 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"}' ``` **Response** · 201 — Created ```json { "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" } } ```
--- ### Remove a contact from a domain {#delete-organizations-organization-domains-domain-contacts-contact}
`DELETE` `/organizations/{organization}/domains/{domain}/contacts/{contact}` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization Unassigns the contact from the domain in every role it held. The contact itself is kept. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | | `contact_id`
path · required | integer | The contact's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X DELETE "https://api.infranest.io/api/organizations/42/domains/1/contacts/1" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 204 — no content
--- ### Get a domain’s transfer code {#get-organizations-organization-domains-domain-epp-code}
`GET` `/organizations/{organization}/domains/{domain}/epp-code` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/epp-code" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ```
--- ### Get a domain’s audit history {#get-organizations-organization-domains-domain-history}
`GET` `/organizations/{organization}/domains/{domain}/history` **Scope:** `domains.read` · **Changes data:** no The 50 most recent audit-log entries for the domain and its manual cost items, newest first. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/history" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json [] ```
--- ### Check a domain’s nameservers {#get-organizations-organization-domains-domain-ns-health}
`GET` `/organizations/{organization}/domains/{domain}/ns-health` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/ns-health" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } } ```
--- ### Get a domain’s registrar pricing {#get-organizations-organization-domains-domain-pricing}
`GET` `/organizations/{organization}/domains/{domain}/pricing` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/pricing" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ```
--- ### Get a domain’s registry record {#get-organizations-organization-domains-domain-registry-record}
`GET` `/organizations/{organization}/domains/{domain}/registry-record` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/registry-record" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "statuses": [], "created_at": null, "updated_at": null, "source": null, "raw": null } ```
--- ### Get how a domain is set up {#get-organizations-organization-domains-domain-setup}
`GET` `/organizations/{organization}/domains/{domain}/setup` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/setup" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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" ] } ```
--- ### Unarchive a domain {#post-organizations-organization-domains-domain-unarchive}
`POST` `/organizations/{organization}/domains/{domain}/unarchive` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl -X POST "https://api.infranest.io/api/organizations/42/domains/1/unarchive" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ```
--- ### Look up a domain’s WHOIS {#get-organizations-organization-domains-domain-whois}
`GET` `/organizations/{organization}/domains/{domain}/whois` **Scope:** `domains.read` · **Changes data:** no A live WHOIS lookup for the domain. Answers 422 with a message when the lookup fails. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `domain_id`
path · required | integer | The domain's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1/whois" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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.…" } ```
--- ### Get a domain {#get-organizations-organization-domains-id}
`GET` `/organizations/{organization}/domains/{id}` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `id`
path · required | integer | The id's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/1" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ] } } ```
--- ### Update a domain {#put-organizations-organization-domains-id}
`PUT` `/organizations/{organization}/domains/{id}` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `id`
path · required | integer | The id's ID. | | `notes`
body | string, nullable | Must not be greater than 10000 characters. | | `tag_ids`
body | array | | | `serves_website`
body | boolean, nullable | | | `expected_issuers`
body | array | Must not be greater than 100 characters. | | `nameservers`
body | array | Must not be greater than 253 characters. | | `registrar_contacts`
body | object, nullable | | | `renewal_price`
body | number, nullable | Must be at least 0. Must not be greater than 9999999.99. | | `renewal_price_currency`
body | string, nullable | Must be 3 characters. | | `billing_interval`
body | string | One of: `hourly`, `daily`, `weekly`, `monthly`, `quarterly`, `yearly`. | | `interval_count`
body | integer | Must be at least 1. Must not be greater than 120. | | `purchase_price`
body | number, nullable | Must be at least 0. Must not be greater than 9999999.99. | | `purchase_price_currency`
body | string, nullable | Must be 3 characters. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`validation_failed`](../errors.md#validation_failed), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh 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."}' ``` **Response** · 200 ```json { "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 } ] } } ```
--- ### Plan CAA protection across domains {#get-organizations-organization-domains-caa-protection-plan}
`GET` `/organizations/{organization}/domains/caa-protection-plan` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `ids`
body | array | | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/caa-protection-plan" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ] } } ] } ```
--- ### Plan email protection across domains {#get-organizations-organization-domains-email-protection-plan}
`GET` `/organizations/{organization}/domains/email-protection-plan` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `mode`
body · required | string | | | `ids`
body | array | | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/email-protection-plan?mode=%3Cmode%3E" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } } ] } ```
--- ### Get the domains overview {#get-organizations-organization-domains-overview}
`GET` `/organizations/{organization}/domains/overview` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/overview" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ```
--- ### List registrar moves {#get-organizations-organization-domains-registrar-moves}
`GET` `/organizations/{organization}/domains/registrar-moves` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/registrar-moves" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "data": [] } ```
--- ### Get registration requirements for an extension {#get-organizations-organization-domains-registration-fields}
`GET` `/organizations/{organization}/domains/registration-fields` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `credential_id`
body · required | integer | Must match an existing stored value. | | `tld`
body | string | | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/registration-fields?credential_id=16" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "fields": [], "unknown": true, "periods": null } ```
--- ### Plan a settings change across domains {#get-organizations-organization-domains-settings-plan}
`GET` `/organizations/{organization}/domains/settings-plan` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `setting`
body · required | string | | | `value`
body | boolean | | | `ids`
body | array | | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh curl "https://api.infranest.io/api/organizations/42/domains/settings-plan?setting=%3Csetting%3E" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Accept: application/json" ``` **Response** · 200 ```json { "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 } ] } ```
--- ### Track a domain by name {#post-organizations-organization-domains-track}
`POST` `/organizations/{organization}/domains/track` **Scope:** `domains.write` · **Changes data:** yes — only where API writes are switched on for the organization 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `name`
body · required | string | Must not be greater than 253 characters. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`write_disabled`](../errors.md#write_disabled), [`organization_suspended`](../errors.md#organization_suspended), [`not_found`](../errors.md#not_found), [`idempotency_in_progress`](../errors.md#idempotency_in_progress), [`validation_failed`](../errors.md#validation_failed), [`idempotency_key_reused`](../errors.md#idempotency_key_reused), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh 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"}' ``` **Response** · 201 — Created ```json { "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 } ```
--- ### Check a domain before transferring it in {#get-organizations-organization-domains-transfer-preflight}
`GET` `/organizations/{organization}/domains/transfer-preflight` **Scope:** `domains.read` · **Changes data:** no 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. | Field | Type | Notes | |---|---|---| | `organization_id`
path · required | integer | Your organization's ID. | | `name`
body · required | string | Must not be greater than 100 characters. | | `tld`
body · required | string | Must not be greater than 30 characters. | | `credential_id`
body | integer, nullable | Which 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. | **Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request** ```sh 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" ``` **Response** · 200 ```json { "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" } } ] } ```