Autenticazione
Tutte le richieste API richiedono l’autenticazione tramite una chiave API. Inserire la chiave nell’header Authorization come token Bearer. La chiave API deve iniziare con il prefisso nxd_.
Requisito del piano: la REST API, l’API compatibile con ISPmanager e i webhook sono disponibili dal piano Pro in su, così come le due funzionalità descritte anche in questo riferimento: DNSSEC e zone secondarie (slave). Una chiave su un piano che non le include riceve un 403.
Authorization: Bearer nxd_your_api_key_here
Il livello di autenticazione API è stateless – ogni richiesta viene autenticata in modo indipendente. Non ci sono sessioni o cookie.
Mantenga segreta la Sua chiave API. Non la condivida nel codice lato client, nei repository pubblici o negli URL. Se una chiave viene compromessa, la revochi immediatamente e ne crei una nuova.
Errori di autenticazione
| Stato | Causa |
|---|---|
401 |
Chiave API mancante o non valida, chiave scaduta o account cancellato |
403 |
Alla chiave manca il permesso richiesto dall’endpoint, oppure il piano dell’account non include l’accesso all’API – il controllo sul piano risponde 403, non 401, su qualsiasi percorso. |
Formato delle risposte
Tutte le risposte sono in formato JSON. Le risposte di successo hanno la seguente struttura:
Risorsa singola
{
"status": "success",
"data": {
"id": "xK9mQ2",
"name": "example.com",
...
}
}
Lista paginata
{
"status": "success",
"data": [ ... ],
"meta": {
"total": 150,
"page": 1,
"per_page": 25,
"last_page": 6
}
}
Risposta di errore
{
"status": "error",
"error": {
"code": "validation_error",
"message": "Validation failed.",
"details": {
"name": ["Domain name is required."]
}
}
}
Gli errori generati a un livello più profondo della piattaforma – una quota, un dominio bloccato, un guasto dei server dei nomi – contengono lo stesso oggetto error ma nessun campo status. Conviene distinguere i casi in base a error.code, che è stabile, e non in base alla presenza di status. Per contratto i messaggi sono in inglese su ogni istanza e in ogni lingua; la parte leggibile dalle macchine è error.code.
ID pubblici
Ogni risorsa è identificata da un id opaco (ad esempio xK9mQ2), usato nei percorsi URL. Gli ID numerici del database non vengono mai esposti né accettati.
Paginazione
Gli endpoint che restituiscono risultati paginati accettano i seguenti parametri di query:
| Parametro | Tipo | Predefinito | Descrizione |
|---|---|---|---|
page |
integer | 1 | Numero di pagina (minimo 1) |
per_page |
integer | 25 | Elementi per pagina (1–100) |
Limitazione delle richieste
Le richieste vengono conteggiate per account, non per chiave, in una finestra scorrevole di un minuto, e il budget dipende dal piano: il valore esatto è indicato nel confronto dei piani sulla pagina dei prezzi. Le richieste non autenticate vengono conteggiate per indirizzo IP. Ogni risposta riporta lo stato attuale del budget, quindi non serve fare stime:
| Intestazione | Significato |
|---|---|
X-RateLimit-Limit | Richieste consentite nella finestra. |
X-RateLimit-Remaining | Richieste rimanenti nella finestra corrente. |
X-RateLimit-Reset | Timestamp Unix in cui la finestra si azzera. |
Retry-After | Secondi di attesa, inviato in caso di 429. |
Per le operazioni di massa – l’importazione di una zona di grandi dimensioni, la riconciliazione di centinaia di record – conviene leggere X-RateLimit-Remaining e fermarsi prima che arrivi a zero, invece di riprovare dopo un 429. La CLI lo fa automaticamente.
Alcune operazioni hanno una finestra propria, più lunga, oltre al budget di richieste: una zona può essere spostata in un altro gruppo di nameserver tre volte al giorno. La risposta indica quale limite è stato raggiunto.
Zone
Gestione delle zone DNS. Richiede zones.read per le operazioni di lettura e zones.write per le operazioni di scrittura.
GET /v1/zones
Elenca tutte le zone dell’utente autenticato.
Parametri di query
search– filtra le zone per nomepage,per_page– paginazione
Campi della risposta
id, name, type (master o slave), status, ns_group, created_at, updated_at
GET /v1/zones/{id}
Ottiene informazioni dettagliate su una zona specifica, inclusi i dati SOA, i server dei nomi e il conteggio dei record.
Campi aggiuntivi della risposta
records_count, soa (campi primary_ns, admin_email, serial, refresh, retry, expire, minimum), nameservers (elenco), ns_group (campi id, slug, name)
POST /v1/zones
Crea una nuova zona DNS. Rifiutata con 409 se il dominio esiste già o si sovrappone alla zona di un altro account, e con 422 se il limite di zone del piano è raggiunto o il dominio è bloccato.
Corpo della richiesta (JSON)
{
"name": "example.com",
"type": "master",
"ns_group": "eu"
}
Una zona secondaria (slave) al suo posto:
{
"name": "example.com",
"type": "slave",
"master_ip": "203.0.113.10"
}
name(obbligatorio) – nome di dominiotype–"master"(predefinito) o"slave"ns_group– gruppo NS a cui assegnare la zona (opzionale, utilizza quello predefinito se omesso)master_ip– obbligatorio per le zone secondarie; deve essere un indirizzo IP pubblico valido
Restituisce 201 Created con l’oggetto zona.
PATCH /v1/zones/{id}
Sposta la zona in un altro gruppo di server dei nomi. È l’unico PATCH dell’API. Permesso: zones.write.
Corpo della richiesta (JSON)
{
"ns_group": "eu"
}
Restituisce la zona come risulta dopo lo spostamento, nella stessa forma di GET /v1/zones/{id}. Il gruppo si indica tramite il suo slug, cioè uno dei valori che GET /v1/ns-groups elenca per il Suo account; qualsiasi altro valore viene rifiutato con un 400.
La zona continua a rispondere per tutta la durata: i nuovi nameserver vengono predisposti prima della risposta e i precedenti continuano a servire le richieste mentre i resolver si aggiornano. Aggiorna poi la delega presso il tuo registrar. Una zona può essere spostata tre volte al giorno; oltre quel limite la chiamata restituisce 429.
DELETE /v1/zones/{id}
Elimina una zona e tutti i suoi record.
Restituisce 204 No Content in caso di successo.
GET /v1/zones/{id}/export
Esporta una zona in formato BIND o come JSON strutturato.
Parametri di query
format–"bind"(predefinito) restituisce il testo del file di zona BIND;"json"restituisce un array strutturato di record con nome, tipo, contenuto e TTL
Record
Gestione dei record DNS all’interno di una zona. Tutti gli endpoint dei record sono annidati sotto una zona. Richiede records.read per le operazioni di lettura e records.write per le operazioni di scrittura.
GET /v1/zones/{zoneId}/records
Elenca tutti i record in una zona.
Parametri di query
type– filtra per tipo di record (es.A,CNAME,MX)name– filtra per nome del record (corrispondenza parziale)search– cerca sia nel nome che nel contenuto
Campi della risposta
id, name, type, content, ttl, disabled, fields (campi specifici del tipo analizzati)
GET /v1/zones/{zoneId}/records/{recordId}
Ottiene un singolo record tramite il suo ID.
POST /v1/zones/{zoneId}/records
Crea un nuovo record DNS.
Corpo della richiesta (JSON)
{
"type": "A",
"name": "www",
"ttl": 3600,
"content": "93.184.216.34"
}
type(obbligatorio) – tipo di record (A, AAAA, CNAME, MX, TXT, SRV, CAA, NS, PTR, ALIAS, DNAME, DS, TLSA)name– nome del record relativo alla zona (predefinito:@per l’apice della zona)ttl– tempo di vita in secondi (predefinito: 3600)content– valore del record (IP per A/AAAA, hostname per CNAME/NS/PTR, testo per TXT, server di posta per MX)
Campi specifici del tipo
- MX:
priority(predefinito: 10) - Record SRV:
priority,weight,port - CAA:
flags(predefinito: 0),tag(predefinito: "issue") - Record DS:
keytag,algorithm,digest_type - Record TLSA:
usage,selector,matching_type
Per MX, SRV, CAA, DS e TLSA il campo content contiene solo il valore principale – il server di posta, la destinazione SRV, il dominio della CA, il solo digest esadecimale – mentre tutto il resto va nei campi elencati sopra. L’invio di dati di record già assemblati (per esempio 0 issue "letsencrypt.org" come contenuto CAA) viene rifiutato con un 400 che indica il campo.
Il TTL appartiene al set di record. Omettendo ttl quando si aggiunge un altro valore a un nome già esistente, si mantiene il TTL corrente; indicandolo, il nuovo TTL viene applicato a tutti i valori presenti su quel nome. Per un nome del tutto nuovo il valore predefinito è 3600 secondi.
Restituisce 201 Created con l’oggetto record.
PUT /v1/zones/{zoneId}/records/{recordId}
Aggiorna un record esistente. Includere solo i campi da modificare; i campi omessi mantengono i valori correnti.
{
"content": "93.184.216.35",
"ttl": 7200
}
Restituisce 200 OK con l’oggetto record aggiornato. Nota: l’ID del record potrebbe cambiare dopo un aggiornamento poiché viene calcolato dal nome, tipo e contenuto del record.
DELETE /v1/zones/{zoneId}/records/{recordId}
Elimina un record dalla zona.
Restituisce 204 No Content in caso di successo.
DNSSEC
Gestione DNSSEC per le zone. Richiede zones.read per visualizzare lo stato e zones.write per abilitare o disabilitare.
GET /v1/zones/{id}/dnssec
Ottiene lo stato DNSSEC di una zona, incluse le chiavi e i record DS.
Campi della risposta
enabled (booleano), keys (array di record DNSKEY), ds_records (array di record DS da impostare presso il registrar)
POST /v1/zones/{id}/dnssec/enable
Abilita DNSSEC per una zona. Genera automaticamente le chiavi di firma.
Restituisce lo stato DNSSEC con le chiavi generate e i record DS.
POST /v1/zones/{id}/dnssec/disable
Disabilita DNSSEC per una zona. Rimuove tutte le chiavi di firma.
Restituisce {"enabled": false, "keys": [], "ds_records": []}.
Gruppi NS
Elenca i gruppi di server dei nomi disponibili. Usare l’id di un gruppo come ns_group durante la creazione di una zona. Questo endpoint può essere letto da qualsiasi chiave API valida.
GET /v1/ns-groups
Elenca i gruppi di server dei nomi attivi.
Campi della risposta per gruppo
id, name, slug
Dettagli account
Visualizzazione delle informazioni dell’account e gestione delle chiavi API.
GET /v1/account
Ottiene le informazioni dell’account corrente, inclusi i dettagli dell’abbonamento.
Campi della risposta
id (formato UUID), email, name, role, status, language, timezone, created_at
subscription – oggetto con plan, billing_cycle, status, current_period_start, current_period_end (o null se nessun abbonamento)
GET /v1/account/api-keys
Elenca tutte le chiavi API dell’utente autenticato.
Campi della risposta per chiave
id, name, key_prefix (primi 8 caratteri), permissions (array), last_used_at, expires_at, created_at
POST /v1/account/api-keys
Crea una nuova chiave API.
Corpo della richiesta (JSON)
{
"name": "CI/CD Pipeline",
"permissions": ["zones.read", "records.read", "records.write"],
"expires_at": "2027-01-01"
}
name(obbligatorio) – nome leggibile (massimo 255 caratteri)permissions(obbligatorio) – array di permessi (almeno uno richiesto):zones.read,zones.write,records.read,records.write,webhooks.read,webhooks.writeexpires_at– data di scadenza opzionale (ISO 8601 oYYYY-MM-DD); deve essere nel futuro
La risposta include la chiave API completa nel campo
key. Questa è l’unica volta in cui la chiave completa viene restituita. La conservi in modo sicuro.
Restituisce 201 Created con i dettagli della chiave incluso il valore completo key.
DELETE /v1/account/api-keys/{id}
Revoca (elimina definitivamente) una chiave API.
Restituisce 204 No Content in caso di successo.
Fatturazione
Visualizzazione di abbonamento, piani e fatture. Questi endpoint sono di sola lettura.
GET /v1/billing/subscription
Ottiene i dettagli dell’abbonamento corrente. Restituisce null se non c’è un abbonamento attivo.
Campi della risposta
Campi id, plan, billing_cycle, status, current_period_start, current_period_end, created_at
GET /v1/billing/plans
Elenca tutti i piani disponibili con tariffe e funzionalità.
Campi della risposta per piano
Campi id, name, slug, description, price_monthly, price_yearly, currency, max_domains, max_records, features (elenco)
GET /v1/billing/invoices
Elenca le fatture dell’utente autenticato, dalle più recenti.
Parametri di query
status– filtra per stato (draft,issued,sent,void)page,per_page– paginazione
GET /v1/billing/invoices/{id}
Ottiene una singola fattura tramite il suo <code>id</code>.
Campi della risposta
Campi id, number, status, amount (lordo), net_amount (netto), tax_amount, tax_rate, currency, issued_at, created_at. Gli importi sono stringhe decimali semplici.
Webhooks
Gestisce gli abbonamenti webhook in uscita per ricevere notifiche in tempo reale sulle modifiche di zone e record. Richiede webhooks.read per la lettura e webhooks.write per creare, modificare o eliminare.
GET /v1/webhooks
Elenca tutti gli abbonamenti webhook dell’utente autenticato.
Campi della risposta per webhook
id, url, events (array), description, is_active, failure_count, last_triggered_at, created_at
POST /v1/webhooks
Crea un abbonamento webhook.
Corpo della richiesta (JSON)
{
"url": "https://example.com/webhook",
"events": ["zone.created", "record.created"],
"description": "Production webhook"
}
url(obbligatorio) – endpoint HTTPS che riceverà i payload degli eventievents(obbligatorio) – array dei tipi di evento a cui iscriversidescription– etichetta leggibile facoltativa
La risposta include un
secretper verificare le firme dei webhook (HMAC). È l’unica volta in cui il secret viene restituito. Conservarlo in un luogo sicuro.
Restituisce 201 Created con l’id e il secret del webhook.
GET /v1/webhooks/{id}
Ottiene un singolo abbonamento webhook con le sue consegne più recenti.
PUT /v1/webhooks/{id}
Aggiorna un abbonamento webhook. Includere solo i campi da modificare.
Restituisce 200 OK con l’oggetto webhook aggiornato.
DELETE /v1/webhooks/{id}
Elimina un abbonamento webhook.
Restituisce 204 No Content in caso di successo.
POST /v1/webhooks/{id}/test
Invia un evento di test all’endpoint del webhook per verificarne la raggiungibilità.
Mette in coda una consegna di test con un payload "type": "test".
Verifica di una consegna
Ogni consegna è firmata con il secret restituito alla creazione del webhook e include quattro header:
X-NexDNS-Signature: sha256=<hmac>
X-NexDNS-Timestamp: 1785370265
X-NexDNS-Event: record.created
X-NexDNS-Delivery: 42
Ricalcolare HMAC-SHA256 sul corpo grezzo esatto della richiesta usando il proprio secret e confrontarlo con il digest esadecimale che segue sha256=, tramite un confronto a tempo costante. Una discrepanza significa che la richiesta non arriva da noi. X-NexDNS-Delivery identifica il singolo tentativo, quindi i tentativi ripetuti dello stesso evento condividono l’id dell’evento ma non il numero di consegna.
Payload della consegna
{
"id": "evt_szpj9u04z8u0",
"type": "record.created",
"created_at": "2026-07-30 00:31:05",
"data": {
"zone": { "name": "example.com" },
"record": { "name": "www.example.com.", "type": "A", "content": "203.0.113.10", "ttl": 3600 }
}
}
Tipi di evento disponibili
È possibile iscriversi a qualsiasi combinazione di questi tipi di evento:
zone.created, zone.updated, zone.deleted, record.created, record.updated, record.deleted, dnssec.enabled, dnssec.disabled, zone.health.problem, zone.health.resolved
Codici di errore
Tutti gli errori seguono un formato coerente con una stringa di errore code e un message leggibile.
| Stato HTTP | Codice errore | Descrizione |
|---|---|---|
400 |
validation_error |
Il corpo della richiesta non ha superato la validazione. Verificare details per errori specifici dei campi. |
401 |
unauthorized |
Chiave API mancante, non valida o scaduta. |
403 |
forbidden |
La chiave API non dispone del permesso richiesto, il piano dell’account non include l’accesso all’API, oppure il piano non include la funzionalità utilizzata (per esempio zone secondarie o DNSSEC). |
404 |
not_found |
La risorsa richiesta non esiste o non è accessibile dall’utente autenticato. |
409 |
conflict |
La risorsa esiste già (es. nome di zona duplicato). |
422 |
quota_exceeded |
Il limite di zone o di record previsto dal piano è stato raggiunto. |
422 |
domain_blacklisted |
Il dominio è nell’elenco dei domini bloccati e non può essere aggiunto. |
429 |
rate_limit_exceeded |
Troppe richieste. Verificare l’header Retry-After. |
500 |
server_error |
Si è verificato un errore interno imprevisto. Riprovi o contatti l’assistenza se il problema persiste. |
502 |
dns_server_error |
I server dei nomi sono temporaneamente non disponibili. La richiesta non è stata applicata: riprovare. |
Esempi di codice
Tutti gli esempi utilizzano curl. Sostituire nxd_your_api_key con la Sua chiave API effettiva.
Elencare le zone
curl -s "https://api.nexdns.tech/v1/zones" \
-H "Authorization: Bearer nxd_your_api_key"
Creare una zona
curl -s -X POST "https://api.nexdns.tech/v1/zones" \
-H "Authorization: Bearer nxd_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "example.com"}'
Aggiungere un record A
curl -s -X POST "https://api.nexdns.tech/v1/zones/{zoneId}/records" \
-H "Authorization: Bearer nxd_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "A",
"name": "www",
"ttl": 3600,
"content": "93.184.216.34"
}'
Aggiungere un record MX
curl -s -X POST "https://api.nexdns.tech/v1/zones/{zoneId}/records" \
-H "Authorization: Bearer nxd_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "MX",
"name": "@",
"ttl": 3600,
"content": "mail.example.com",
"priority": 10
}'
Aggiornare un record
curl -s -X PUT "https://api.nexdns.tech/v1/zones/{zoneId}/records/{recordId}" \
-H "Authorization: Bearer nxd_your_api_key" \
-H "Content-Type: application/json" \
-d '{"content": "93.184.216.35", "ttl": 7200}'
Eliminare un record
curl -s -X DELETE "https://api.nexdns.tech/v1/zones/{zoneId}/records/{recordId}" \
-H "Authorization: Bearer nxd_your_api_key"
Esportare una zona (formato BIND)
curl -s "https://api.nexdns.tech/v1/zones/{zoneId}/export" \
-H "Authorization: Bearer nxd_your_api_key"
Abilitare DNSSEC
curl -s -X POST "https://api.nexdns.tech/v1/zones/{zoneId}/dnssec/enable" \
-H "Authorization: Bearer nxd_your_api_key"
Creare una chiave API
curl -s -X POST "https://api.nexdns.tech/v1/account/api-keys" \
-H "Authorization: Bearer nxd_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Read-only key",
"permissions": ["zones.read", "records.read"],
"expires_at": "2027-12-31"
}'
Ottenere le informazioni dell’account
curl -s "https://api.nexdns.tech/v1/account" \
-H "Authorization: Bearer nxd_your_api_key"