- API Reference
- Domain
- Import a DNS zone file into a Project, or preview it with dry-run
Import a DNS zone file into a Project, or preview it with dry-run
Parses an uploaded RFC-1035 zone file and returns the structured import plan: the importable target DNSZones (one per distinct owner name, with the record sets that would be set) plus a flat list of conflicts explaining everything that will not be imported (invalid records, unsupported record types, CNAME conflicts, placement problems, parse errors). With dryRun=true this is all it does — a side-effect-free preview, nothing is created. Otherwise it also starts the import and returns the created job id. The import is all-or-nothing: if the zone file has any conflict the request is rejected with 412 and no job is created — resolve the conflicts (visible in the dry-run preview) and retry, since a half-imported zone file would leave DNS in a confusing half-state. An identical import still running for the project is rejected with 409. Existing zones are overwritten. Poll GET /v2/dns-zone-imports/{zoneFileImportId} for status.
Request
- projectIdstringrequired
ID of the Project to import into.
- dryRunboolean
When true, only preview the import (no zones are created and no import job is started).
- zoneFilestringrequired
Raw RFC-1035 zone file content to import.
Content-Type: application/json
{
"zoneFile": "string"
}
{
"properties": {
"zoneFile": {
"description": "Raw RFC-1035 zone file content to import.",
"type": "string"
}
},
"required": [
"zoneFile"
],
"type": "object"
}
Responses
The import plan (zones + conflicts); on a real import also the created job id.
- conflictsarray of objectrequired
Everything that will not be imported (invalid records, unsupported record types, CNAME conflicts, placement problems, parse errors). Empty on a real import, since any conflict rejects the whole import with 412 (all-or-nothing).
- Array[
- *object
- codestring (one of: parseError, invalidRecord, invalidZoneName, unsupportedRecordType, cnameConflict, foreignCustomerIngress, rootZoneUnavailable)required
Machine-readable conflict kind: parseError (a zone-file line could not be parsed), invalidRecord (a record failed the same schema validation the write commands apply), invalidZoneName (the owner name is not a valid zone name, e.g. a wildcard *.example.com), unsupportedRecordType (an RR type dns-service does not import), cnameConflict (a CNAME shares a name with other record types), foreignCustomerIngress (the zone's enabled ingress belongs to another organization), rootZoneUnavailable (a subzone whose root zone is neither importable nor already existing).
- messagestringrequired
Human-readable explanation of the conflict, suitable for surfacing to the user.
- namestring
Offending record/owner name. Empty for a file-level parse error, where sourceLine locates the bad line.
- recordstring
Only on an invalidRecord conflict: the offending record's rendered value (e.g. "10 ." for an MX).
- recordSetTypestring (one of: a, mx, txt, cname, srv, caa)
Only on an invalidRecord conflict: the offending record's set type.
- sourceLineinteger (int64)
1-based line number in the uploaded zone file, set for a file-level parse error (code parseError); 0 otherwise.
]
- idstring (uuid)
ID of the started import job. Absent on a dry-run (dryRun=true), which creates no job.
- zonesarray of objectrequired
The importable target zones (one per distinct owner name), each with the record sets that would be set. On a dry-run this is the preview; on a real import it is the plan that was applied.
- Array[
- *object
- alreadyExistsbooleanrequired
Whether a zone with this name already exists. On import its record sets are overwritten rather than the import failing.
- namestringrequired
Fully-qualified name of the target zone. Every distinct owner name becomes its own zone. Only importable zones are listed; a zone named by a conflict is omitted.
- recordSetsarray of objectrequired
The record sets that would be set on the zone — one per record type present for this owner name.
- Array[
- *object
- recordsarray of objectrequired
The individual records in the set.
- Array[
- *object
- flagsinteger (int32)
CAA flags. Only set for CAA records.
- portinteger (int32)
SRV port. Only set for SRV records.
- priorityinteger (int32)
MX preference / SRV priority. Only set for MX and SRV records.
- tagstring
CAA tag (e.g. issue, issuewild, iodef). Only set for CAA records.
- valuestringrequired
The record's value: an IP address for A/AAAA, the target FQDN for MX/CNAME/SRV, the text for TXT, the value for CAA.
- weightinteger (int32)
SRV weight. Only set for SRV records.
]
- ttlNormalizedbooleanrequired
True when the source TTLs had to be normalized to ttlSeconds — because they diverged within the set or fell below the 60s minimum. Informational; the import still uses ttlSeconds.
- ttlSecondsinteger (int32)required
TTL applied to the whole set, in seconds. Collapsed to a single value across the set: the minimum of the source TTLs, floored to the 60s minimum.
- typestring (one of: a, mx, txt, cname, srv, caa)required
Record-set type.
]
- targetProjectIdstringrequired
Project the zone would be created in. Always set, since only importable zones are listed.
]
Content-Type: application/json
{
"conflicts": [
{
"code": "parseError",
"message": "string",
"name": "string",
"record": "string",
"recordSetType": "a",
"sourceLine": 123
}
],
"id": "f0f86186-0a5a-45b2-aa33-502777496347",
"zones": [
{
"alreadyExists": true,
"name": "string",
"recordSets": [
{
"records": [
{
"flags": 123,
"port": 123,
"priority": 123,
"tag": "string",
"value": "string",
"weight": 123
}
],
"ttlNormalized": true,
"ttlSeconds": 123,
"type": "a"
}
],
"targetProjectId": "string"
}
]
}
{
"properties": {
"conflicts": {
"description": "Everything that will not be imported (invalid records, unsupported record types, CNAME conflicts, placement problems, parse errors). Empty on a real import, since any conflict rejects the whole import with 412 (all-or-nothing).",
"items": {
"properties": {
"code": {
"description": "Machine-readable conflict kind: parseError (a zone-file line could not be parsed), invalidRecord (a record failed the same schema validation the write commands apply), invalidZoneName (the owner name is not a valid zone name, e.g. a wildcard *.example.com), unsupportedRecordType (an RR type dns-service does not import), cnameConflict (a CNAME shares a name with other record types), foreignCustomerIngress (the zone's enabled ingress belongs to another organization), rootZoneUnavailable (a subzone whose root zone is neither importable nor already existing).",
"enum": [
"parseError",
"invalidRecord",
"invalidZoneName",
"unsupportedRecordType",
"cnameConflict",
"foreignCustomerIngress",
"rootZoneUnavailable"
],
"type": "string"
},
"message": {
"description": "Human-readable explanation of the conflict, suitable for surfacing to the user.",
"type": "string"
},
"name": {
"description": "Offending record/owner name. Empty for a file-level parse error, where sourceLine locates the bad line.",
"type": "string"
},
"record": {
"description": "Only on an invalidRecord conflict: the offending record's rendered value (e.g. \"10 .\" for an MX).",
"type": "string"
},
"recordSetType": {
"description": "Only on an invalidRecord conflict: the offending record's set type.",
"enum": [
"a",
"mx",
"txt",
"cname",
"srv",
"caa"
],
"type": "string"
},
"sourceLine": {
"description": "1-based line number in the uploaded zone file, set for a file-level parse error (code parseError); 0 otherwise.",
"format": "int64",
"type": "integer"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"type": "array"
},
"id": {
"description": "ID of the started import job. Absent on a dry-run (dryRun=true), which creates no job.",
"format": "uuid",
"type": "string"
},
"zones": {
"description": "The importable target zones (one per distinct owner name), each with the record sets that would be set. On a dry-run this is the preview; on a real import it is the plan that was applied.",
"items": {
"properties": {
"alreadyExists": {
"description": "Whether a zone with this name already exists. On import its record sets are overwritten rather than the import failing.",
"type": "boolean"
},
"name": {
"description": "Fully-qualified name of the target zone. Every distinct owner name becomes its own zone. Only importable zones are listed; a zone named by a conflict is omitted.",
"type": "string"
},
"recordSets": {
"description": "The record sets that would be set on the zone — one per record type present for this owner name.",
"items": {
"properties": {
"records": {
"description": "The individual records in the set.",
"items": {
"properties": {
"flags": {
"description": "CAA flags. Only set for CAA records.",
"format": "int32",
"type": "integer"
},
"port": {
"description": "SRV port. Only set for SRV records.",
"format": "int32",
"type": "integer"
},
"priority": {
"description": "MX preference / SRV priority. Only set for MX and SRV records.",
"format": "int32",
"type": "integer"
},
"tag": {
"description": "CAA tag (e.g. issue, issuewild, iodef). Only set for CAA records.",
"type": "string"
},
"value": {
"description": "The record's value: an IP address for A/AAAA, the target FQDN for MX/CNAME/SRV, the text for TXT, the value for CAA.",
"type": "string"
},
"weight": {
"description": "SRV weight. Only set for SRV records.",
"format": "int32",
"type": "integer"
}
},
"required": [
"value"
],
"type": "object"
},
"type": "array"
},
"ttlNormalized": {
"description": "True when the source TTLs had to be normalized to ttlSeconds — because they diverged within the set or fell below the 60s minimum. Informational; the import still uses ttlSeconds.",
"type": "boolean"
},
"ttlSeconds": {
"description": "TTL applied to the whole set, in seconds. Collapsed to a single value across the set: the minimum of the source TTLs, floored to the 60s minimum.",
"format": "int32",
"type": "integer"
},
"type": {
"description": "Record-set type.",
"enum": [
"a",
"mx",
"txt",
"cname",
"srv",
"caa"
],
"type": "string"
}
},
"required": [
"type",
"ttlSeconds",
"ttlNormalized",
"records"
],
"type": "object"
},
"type": "array"
},
"targetProjectId": {
"description": "Project the zone would be created in. Always set, since only importable zones are listed.",
"type": "string"
}
},
"required": [
"name",
"alreadyExists",
"recordSets",
"targetProjectId"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"zones",
"conflicts"
],
"type": "object"
}
Validation Error caused by invalid input data in the request
- type"ValidationError"required
- messagestring
- validationErrorsarray of objectrequired
- Array[
- *object
- messagestringrequired
The standard error message
- pathstringrequired
The path to the part of the data that was validated. JavaScript property access notation (e.g., ".prop[1].subProp") is used.
- typestringrequired
ajv validation error type (e.g. "format", "required", "type") or own validation error types
- contextobject
The object with the additional information about the error that can be used to create custom error messages. Keys depend on the type that failed validation (e.g. "missingProperty" for type "required")
- *string
]
Content-Type: application/json
{
"type": "ValidationError",
"message": "Validation failed",
"validationErrors": [
{
"message": "should be string",
"path": ".address.street",
"type": "format",
"context": {
"format": "email"
}
}
]
}
{
"type": "object",
"required": [
"type",
"validationErrors"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ValidationError"
]
},
"message": {
"type": "string",
"example": "Validation failed"
},
"validationErrors": {
"type": "array",
"items": {
"type": "object",
"required": [
"message",
"path",
"type"
],
"properties": {
"message": {
"type": "string",
"description": "The standard error message",
"example": "should be string"
},
"path": {
"type": "string",
"description": "The path to the part of the data that was validated. JavaScript property access notation (e.g., \".prop[1].subProp\") is used.\n",
"example": ".address.street"
},
"type": {
"type": "string",
"description": "ajv validation error type (e.g. \"format\", \"required\", \"type\") or own validation error types",
"example": "format"
},
"context": {
"type": "object",
"example": {
"format": "email"
},
"description": "The object with the additional information about the error that can be used to create custom error messages. Keys depend on the\ntype that failed validation (e.g. \"missingProperty\" for type \"required\")\n",
"additionalProperties": {
"type": "string"
}
}
}
}
}
}
}
An unexpected Error that occurred while handling the request
- messagestringrequired
- typestringrequired
Content-Type: application/json
{
"message": "Something went wrong",
"type": "InternalServerError"
}
{
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"message": {
"type": "string",
"example": "Something went wrong"
},
"type": {
"type": "string",
"example": "InternalServerError"
}
}
}
An unexpected Error that occurred while handling the request
- messagestringrequired
- typestringrequired
Content-Type: application/json
{
"message": "Something went wrong",
"type": "InternalServerError"
}
{
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"message": {
"type": "string",
"example": "Something went wrong"
},
"type": {
"type": "string",
"example": "InternalServerError"
}
}
}
An unexpected Error that occurred while handling the request
- messagestringrequired
- typestringrequired
Content-Type: application/json
{
"message": "Something went wrong",
"type": "InternalServerError"
}
{
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"message": {
"type": "string",
"example": "Something went wrong"
},
"type": {
"type": "string",
"example": "InternalServerError"
}
}
}
Your request ran into a rate limit. You have to wait until rate limit expires
- messagestring
- typestring
Content-Type: application/json
{
"message": "too many requests",
"type": "RateLimitError"
}
{
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "too many requests"
},
"type": {
"type": "string",
"example": "RateLimitError"
}
}
}
An unexpected Error that occurred while handling the request
- messagestringrequired
- typestringrequired
Content-Type: application/json
{
"message": "Something went wrong",
"type": "InternalServerError"
}
{
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"message": {
"type": "string",
"example": "Something went wrong"
},
"type": {
"type": "string",
"example": "InternalServerError"
}
}
}
Usage examples
$ curl \
--fail \
--location \
-X POST \
-d '{"zoneFile":"string"}' \
-H "Authorization: Bearer $MITTWALD_API_TOKEN" \
-H 'Content-Type: application/json' \
https://api.mittwald.de/v2/projects/string/dns-zone-imports?dryRun=true
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { assertStatus } from "@mittwald/api-client-commons";
const client = MittwaldAPIClient.newWithToken(process.env.MITTWALD_API_TOKEN);
const response = await client.domain.dnsCreateDnsZoneFileImport({
"projectId": "string",
"data": {
"zoneFile": "string"
},
"queryParameters": {
"dryRun": true
}
});
assertStatus(response, 200);
use \Mittwald\ApiClient\Generated\V2\Clients\Domain\DnsCreateDnsZoneFileImport\DnsCreateDnsZoneFileImportRequest;
use \Mittwald\ApiClient\Generated\V2\Clients\Domain\DnsCreateDnsZoneFileImport\DnsCreateDnsZoneFileImportRequestBody;
$client = MittwaldAPIClient::newWithToken(getenv('MITTWALD_API_TOKEN'));
// TODO: Please consult the properties and constructor signature of
// DnsCreateDnsZoneFileImportRequestBody to learn how to construct a valid instance
$body = new DnsCreateDnsZoneFileImportRequestBody(/* TODO: ... */);
$request = (new DnsCreateDnsZoneFileImportRequest(
projectId: "string",
body: $body
))
->withDryRun(true);
$response = $client->domain()->dnsCreateDnsZoneFileImport($request);
var_dump($response->getBody();