From e7005fa83f6271d0452d12fc04845b071785507e Mon Sep 17 00:00:00 2001 From: sbarbett Date: Tue, 17 Jun 2025 20:55:37 -0400 Subject: [PATCH] adding response examples --- CHANGELOG.md | 10 + src/UDNS.postman_collection.json | 7242 ++++++++++++++++++++++-------- 2 files changed, 5438 insertions(+), 1814 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b8101d..c9440d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Response examples for all endpoints + +### Fixed +- Pre-request script for rrset delete + +### Removed +- Subaccount section + - Will create as a separate collection in the future + ## [1.0.0] - 2025-06-17 ### Added diff --git a/src/UDNS.postman_collection.json b/src/UDNS.postman_collection.json index 8d96cd3..24fc047 100644 --- a/src/UDNS.postman_collection.json +++ b/src/UDNS.postman_collection.json @@ -1,1816 +1,5430 @@ { - "info": { - "name": "API Documentation", - "description": "This Postman collection provides a sample interface to the UltraDNS (UDNS) REST API. It\u2019s organized around resource\u2011focused folders:\n\n- **Zones**: create, read, update, and delete DNS zones and records\n \n- **Reports**: retrieve usage statistics and analytics\n \n- **\u2026other resources**: each top\u2011level or subfolder groups related endpoints\n \n\nA global pre\u2011request script handles authentication and common helpers:\n\n1. **Reads** your `username` and `password` from the selected environment\n \n2. **Requests** a bearer token and saves it to `{{bearerToken}}`\n \n3. **Automatically refreshes** the token when it expires\n \n4. **Exposes** utility functions on the `utils` object\n \n\n**Setup before running:**\n\n1. Select the appropriate Postman environment.\n \n2. Define `username` and `password` as environment variables.\n \n\n**Using helpers:**\n\n``` js\n// call any helper in scripts or tests\nutils.functionName(arg1, arg2)\n\n ```\n\nWith this in place, every folder and request can focus on its specific API logic, while authentication and shared utilities stay centralized.", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "Zones", - "item": [ - { - "name": "List Zones", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/v3/zones", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v3", - "zones" - ] - }, - "description": "Retrieves all DNS zones in your account. The response returns an array of zone objects, each including details such as zone name, status, default TTL, and name servers." - }, - "response": [] - }, - { - "name": "List Zone Properties", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/v3/zones/{{zones_zoneName}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v3", - "zones", - "{{zones_zoneName}}" - ] - }, - "description": "Retrieves metadata for a specific DNS zone, including record count, name servers, status, type, and other zone\u2011level properties. Requires the `zones_zoneName` path variable." - }, - "response": [] - }, - { - "name": "Create Zone", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"username\",\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"properties\":{\n \"name\":\"{{zones_zoneName}}\",\n \"accountName\":\"{{username}}\",\n \"type\":\"PRIMARY\"\n },\n \"primaryCreateInfo\":{\n \"forceImport\":true,\n \"createType\":\"NEW\"\n },\n \"changeComment\":\"Create zone as agreed\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/v3/zones", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v3", - "zones" - ] - }, - "description": "Creates a new DNS zone. The request body must include:\n\n- **properties.name**: zones_zoneName (the name of the new zone)\n \n- **properties.accountName**: username (your UltraDNS account)\n \n- **properties.type**: PRIMARY\n \n- **primaryCreateInfo.forceImport**: true or false\n \n- **primaryCreateInfo.createType**: NEW or IMPORT\n \n- **changeComment**: free\u2011form text describing why the zone is being created\n \n\nMake sure the environment variables\u202fzones_zoneName\u202fand\u202fusername\u202fare set before running this request." - }, - "response": [] - }, - { - "name": "List Zone Web Forwards", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/v3/zones/{{zones_zoneName}}/webforwards", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v3", - "zones", - "{{zones_zoneName}}", - "webforwards" - ] - }, - "description": "Retrieves all web\u2011forward rules configured for a specific DNS zone. Requires the `zone_zoneName` environment variable. The response returns an array of web\u2011forward objects, each including fields such as:\n\n- `guid` (the forward\u2019s unique ID)\n \n- `requestTo` (the hostname being forwarded)\n \n- `defaultRedirectTo` (the target URL)\n \n- `defaultForwardType` (301, 302, etc.)" - }, - "response": [] - }, - { - "name": "Initiate Zone(s) Export", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"zoneNames\": [\n \"{{zones_zoneName}}\"\n ]\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/v3/zones/export", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v3", - "zones", - "export" - ] - }, - "description": "Initiates an export job for the specified DNS zone. Requires the\u202f`zones_zoneName`\u202fenvironment variable.\n\nOn success, returns **202\u202fAccepted** with an `x-task-id` header containing the export job ID. Use the Task endpoints to poll for status and retrieve the exported zone file." - }, - "response": [] - }, - { - "name": "Create Snapshot", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/v1/zones/{{zones_zoneName}}/snapshot", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v1", - "zones", - "{{zones_zoneName}}", - "snapshot" - ] - }, - "description": "Creates a point\u2011in\u2011time snapshot of the specified DNS zone, replacing any existing snapshot. Requires the\u202f`zones_zoneName`\u202fenvironment variable.\n\n- On success, returns **202\u202fAccepted** with an `x-task-id` header containing the snapshot job ID\n \n- Use the Task endpoints to poll for status and confirm completion before attempting to restore or export the snapshot" - }, - "response": [] - }, - { - "name": "Restore Snapshot", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/v1/zones/{{zones_zoneName}}/restore", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v1", - "zones", - "{{zones_zoneName}}", - "restore" - ] - }, - "description": "Restores the specified DNS zone to its most recent snapshot, overwriting the current configuration. This action is **destructive and irreversible**. Requires the\u202f`zones_zoneName`\u202fenvironment variable.\n\nOn success, returns **202\u202fAccepted** with an `x-task-id` header containing the restore job ID. Use the Task endpoints to poll for status and confirm completion." - }, - "response": [] - }, - { - "name": "Request Zone Transfer", - "request": { - "method": "POST", - "header": [], - "url": { - "raw": "https://api.ultradns.com/zones/{{zones_zoneName}}/transfer", - "protocol": "https", - "host": [ - "api", - "ultradns", - "com" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "transfer" - ] - }, - "description": "Requests a synchronization of the specified secondary DNS zone. Requires the\u202f`zones_zoneName`\u202fenvironment variable.\n\nOn success, returns **200\u202fOK**. You can verify the transfer by fetching the zone details and checking the serial or record changes." - }, - "response": [] - } - ], - "description": "This folder contains all operations for managing the lifecycle and metadata of your DNS zones. Use these endpoints to:\n\n- **Create** new zones\n \n- **Retrieve** zone details and metadata\n \n- **Update** zone configuration\n \n- **Delete** existing zones\n \n- **Export** zone files\n \n- **Capture** zone snapshots\n \n\nEverything here is focused on DNS zone management and its associated metadata.", - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ] - }, - { - "name": "Records", - "item": [ - { - "name": "List RRsets", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "var query_params = {\r", - " // Query will look something like this: q=ttl:300+kind:RECORDS. Potential values:\r", - " // * ttl:String (number >= 0. Only valid for kind=RECORDS)\r", - " // * owner:String (partial match of owner name)\r", - " // * value:String (partial match of rdata, RECORDS kind only)\r", - " // * kind:ALL|RECORDS|POOLS|RD_POOLS|DIR_POOLS|SB_POOLS|TC_POOLS\r", - " // This value for q will query for all regular records with TTL of 300 and owner name containing \"www\":\r", - " //'q': 'ttl:300+kind:RECORDS+owner:www',\r", - " //'offset': '0',\r", - " //'limit': '100',\r", - " //'sort': 'OWNER',\r", - " //'reverse': 'false',\r", - " //'systemGeneratedStatus': 'true',\r", - "}\r", - "\r", - "for (let key in query_params) {\r", - " console.log(key, query_params[key])\r", - " pm.request.url.query.add({key: key, value: query_params[key]})\r", - "}" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{records_zoneName}}", - "rrsets" - ] - }, - "description": "Retrieves all resource record sets (RRSets) in the specified DNS zone. Requires the `records_zoneName` environment variable.\n\nSupports optional query parameters to filter results (for example, by record type, ownerName, TTL) or paginate the list." - }, - "response": [] - }, - { - "name": "List Records by Type", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "var query_params = {\r", - " // Query will look something like this: q=ttl:300+kind:RECORDS. Potential values:\r", - " // * ttl:String (number >= 0. Only valid for kind=RECORDS)\r", - " // * owner:String (partial match of owner name)\r", - " // * value:String (partial match of rdata, RECORDS kind only)\r", - " // * kind:ALL|RECORDS|POOLS|RD_POOLS|DIR_POOLS|SB_POOLS|TC_POOLS\r", - " // This value for q will query for all regular records with TTL of 300 and owner name containing \"www\":\r", - " //'q': 'ttl:300+kind:RECORDS+owner:www',\r", - " //'offset': '0',\r", - " //'limit': '100',\r", - " //'sort': 'OWNER',\r", - " //'reverse': 'false',\r", - " //'systemGeneratedStatus': 'true',\r", - "}\r", - "\r", - "for (let key in query_params) {\r", - " console.log(key, query_params[key])\r", - " pm.request.url.query.add({key: key, value: query_params[key]})\r", - "}" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{records_zoneName}}", - "rrsets", - "{{records_type}}" - ] - }, - "description": "Retrieves all resource record sets (RRSets) of a specific type within the specified DNS zone. Requires the `records_zoneName` and `records_type` environment variables. Set `records_type` to the desired record type (e.g., A, CNAME, TXT) to filter the results. The response returns an array of matching RRSet objects." - }, - "response": [] - }, - { - "name": "List Pools", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/v3/zones/{{records_zoneName}}/rrsets?q=kind:POOLS", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v3", - "zones", - "{{records_zoneName}}", - "rrsets" - ], - "query": [ - { - "key": "q", - "value": "kind:POOLS" - } - ] - }, - "description": "Retrieves all traffic\u2011management pools (RRSets configured for advanced DNS features) in the specified DNS zone. Requires the\u202f`records_zoneName`\u202fenvironment variable. The response returns an array of pool RRSet objects, each including its pool-specific metadata." - }, - "response": [] - }, - { - "name": "Create RRset", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "// Variables to control record creation. This is much easier than switching back and forth\r", - "// to the environment in order to update these parameters: \r", - "//\r", - "// * TODO: Specify values for ownerName, recordType, recordTtl, and recordRdata\r", - "\r", - "const ownerName = '{{records_ownerName}}';\r", - "const recordType = '{{records_type}}';\r", - "const recordTtl = '300';\r", - "\r", - "// Examples of recordRdata:\r", - "// * A: 1.1.1.1\r", - "// * CNAME: www.example.com\r", - "// * MX: 10 mail.example.com\r", - "// * MX (NULL): 0 .\r", - "\r", - "const recordRdata = '1.1.1.1';\r", - "\r", - "const bodyContent = {\r", - " 'ttl': recordTtl,\r", - " 'rdata': [\r", - " recordRdata\r", - " ]\r", - "}\r", - "\r", - "// Convert the JavaScript object to a JSON string\r", - "const bodyContentString = JSON.stringify(bodyContent);\r", - "\r", - "// Set the environment variable with the JSON string\r", - "pm.environment.set(\"requestBody\", bodyContentString);\r", - "\r", - "// Update environment variables to reflect record being configured\r", - "//pm.environment.set('records_ownerName', ownerName);\r", - "//pm.environment.set('records_type', recordType);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{{requestBody}}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{records_zoneName}}", - "rrsets", - "{{records_type}}", - "{{records_ownerName}}" - ] - }, - "description": "Creates a new resource record set (RRSet) in the specified DNS zone.\n\n- **Required variables:**\n \n - `records_zoneName` \u2013 target DNS zone\n \n - `records_ownerName` \u2013 owner name (record label)\n \n - `records_type` \u2013 record type (A, CNAME, MX, etc.)\n \n- **Body construction:** \n A pre\u2011request script reads these environment vars plus:\n \n - `recordTtl` (default \u201c300\u201d)\n \n - `recordRdata` (e.g. \u201c1.1.1.1\u201d for A records) \n It builds an object (`{ ttl: recordTtl, rdata: [ recordRdata ] }`), stringifies it, and sets it to the `requestBody` environment variable." - }, - "response": [] - }, - { - "name": "Delete RRset", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "if (pm.response.code == '204') {\r", - " console.log(\"Delete happened immediately!\");\r", - "} else if (pm.response.code == '202') {\r", - " console.log(\"Delete happened in background!\");\r", - " console.log(\"X-Task-ID: \" + pm.response.headers.get('X-Task-ID'));\r", - "} else {\r", - " console.log(\"Delete Response (status code == \" + pm.response.code + \")!\");\r", - "}" - ], - "type": "text/javascript", - "packages": {} - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "pm.environment.set('records_type', 'A');\r", - "pm.environment.set('records_ownerName', '');" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{records_zoneName}}", - "rrsets", - "{{records_type}}", - "{{records_ownerName}}" - ] - }, - "description": "Deletes the specified resource record set (RRSet) from the given DNS zone.\n\n- **Required variables:**\n \n - records_zoneName \u2013 the DNS zone containing the RRSet\n \n - records_ownerName \u2013 the owner name (record label) of the RRSet\n \n - records_type \u2013 the record type (A, CNAME, TXT, etc.)" - }, - "response": [] - }, - { - "name": "Update RRset", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "if (pm.response.code == '200') {\r", - " console.log(\"Update happened immediately!\");\r", - "} else if (pm.response.code == '202') {\r", - " console.log(\"Update happened in background!\");\r", - " console.log(\"X-Task-ID: \" + pm.response.headers.get('X-Task-ID'));\r", - "} else {\r", - " console.log(\"Update Response (status code == \" + pm.response.code + \")!\");\r", - "}" - ], - "type": "text/javascript", - "packages": {} - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "// NOTE: You must provide ALL record information. \r", - "// Any resource records not included will be removed from the RRSet.\r", - "// It is recommended that you call \"List RRset\" first to get an RRset DTO that you\r", - "// can modify and then send to this \"Update RRset\" API.\r", - "// \r", - "// Variables to control record update. This is much easier than switching back and forth\r", - "// to the environment in order to update these parameters: \r", - "//\r", - "// * TODO: Specify values for ownerName, recordType, recordTtl, and recordRdata\r", - "\r", - "const ownerName = '{{records_ownerName}}';\r", - "const recordType = '{{records_type}}';\r", - "const recordTtl = '300';\r", - "\r", - "// Examples of recordRdata:\r", - "// * A: 1.1.1.1\r", - "// * CNAME: www.example.com\r", - "// * MX: 10 mail.example.com\r", - "// * MX (NULL): 0 .\r", - "\r", - "const recordRdata = '1.1.1.1';\r", - "\r", - "const bodyContent = {\r", - " 'ttl': recordTtl,\r", - " 'rdata': [\r", - " recordRdata\r", - " ]\r", - "}\r", - "\r", - "// Convert the JavaScript object to a JSON string\r", - "const bodyContentString = JSON.stringify(bodyContent);\r", - "\r", - "// Set the environment variable with the JSON string\r", - "pm.environment.set(\"requestBody\", bodyContentString);\r", - "\r", - "// Update environment variables to reflect record being configured\r", - "//pm.environment.set('records_ownerName', ownerName);\r", - "//pm.environment.set('records_type', recordType);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{{requestBody}}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{records_zoneName}}", - "rrsets", - "{{records_type}}", - "{{records_ownerName}}" - ] - }, - "description": "Updates an existing resource record set (RRSet) in the specified DNS zone.\n\n- **Required variables:**\n \n - records_zoneName \u2013 the DNS zone containing the RRSet\n \n - records_ownerName \u2013 the owner name (record label) of the RRSet\n \n - records_type \u2013 the record type (A, CNAME, MX, etc.)\n \n- **Body construction:**\n \n A pre-request script builds the `requestBody` object with your `recordTtl` and `recordRdata`, stringifies it, and sets it to the `requestBody` environment variable. Any records not included in this body will be removed from the RRSet." - }, - "response": [] - } - ], - "description": "This folder includes all endpoints for managing resource record sets (RRSets) within a DNS zone. Each RRSet groups records sharing the same owner name, type, and class (always IN). Record data is handled via the `rdata` array, which follows the BIND presentation format.\n\nUse these endpoints to:\n\n- **List** all RRSets in a zone\n \n- **Retrieve** a specific RRSet by owner name and type\n \n- **Create/Update** RRSets by supplying `rdata` entries and TTL\n \n- **Delete** RRSets\n \n\nPre\u2011request scripts in this folder help initialize variables like `zoneName`, `ownerName`, and `recordType`. Run these scripts or set the corresponding environment variables before making calls." - }, - { - "name": "Tasks", - "item": [ - { - "name": "Check Task", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"currentTask\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/tasks/{{currentTask}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "tasks", - "{{currentTask}}" - ] - }, - "description": "Checks the status of a background task. Requires the `currentTask` variable, which the collection automatically populates from the x-task-id header of previous async operations." - }, - "response": [] - }, - { - "name": "Task Result", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"currentTask\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/tasks/{{currentTask}}/result", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "tasks", - "{{currentTask}}", - "result" - ] - }, - "description": "Retrieves the final result of a completed background task. Requires the `currentTask` variable, which the collection automatically populates from the x-task-id header of prior async requests. Returns the task\u2019s result payload when finished." - }, - "response": [] - } - ], - "description": "This folder contains endpoints for monitoring asynchronous background tasks (e.g., zone snapshots or exports):\n\n- When you invoke an operation that returns **202 Accepted**, the response headers include an `x-task-id`.\n \n- The collection\u2019s pre\u2011request scripts save that ID to the `{{currentTask}}` variable.\n \n- Use these endpoints to:\n \n - **Check status** of the task referenced by `{{currentTask}}`\n \n - **Retrieve results** once the task completes\n \n- Running any new task\u2011generating request will overwrite `{{currentTask}}`, so poll status before kicking off another job." - }, - { - "name": "Reports", - "item": [ - { - "name": "Create NXDomain Report", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "if (utils.isNotSet(pm.environment.get(\"reports_startDate\")) && utils.isNotSet(pm.environment.get(\"reports_endDate\"))) {", - " // If either value isn't set then use a default of the last 30 days", - " const reportDates = utils.lastXDays(30);", - "", - " pm.environment.set(\"reports_startDate\", reportDates[\"start\"]);", - " pm.environment.set(\"reports_endDate\", reportDates[\"end\"]);", - "}", - "", - "const requiredVariables = [\"zones_zoneName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"hostQueryVolume\": {\n \"startDate\": \"{{reports_startDate}}\",\n \"endDate\": \"{{reports_endDate}}\",\n \"zoneNames\": [\n \"{{zones_zoneName}}\"\n ]\n },\n \"sortFields\": {\n \"nxdomainCount\": \"DESC\"\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/v1/reports/dns_resolution/query_volume/host?advance=true&reportType=ADVANCED_NXDOMAINS&limit=100000", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v1", - "reports", - "dns_resolution", - "query_volume", - "host" - ], - "query": [ - { - "key": "advance", - "value": "true" - }, - { - "key": "reportType", - "value": "ADVANCED_NXDOMAINS" - }, - { - "key": "limit", - "value": "100000" - } - ] - }, - "description": "Retrieves an advanced NXDOMAIN report, breaking down \u201cno-such-domain\u201d responses by host over a specified date range. This call is asynchronous and returns a JSON payload containing a `requestId` (saved automatically to `reports_requestId`). If you don\u2019t set `reports_startDate` or `reports_endDate`, a pre-request script defaults them to the last 30 days.\n\n**Required variables**\n\n- `reports_startDate` \u2013 report start date (YYYY-MM-DD)\n \n- `reports_endDate` \u2013 report end date (YYYY-MM-DD)\n \n- `zones_zoneName` \u2013 DNS zone to include in the report\n \n\n**Query parameters**\n\n- `advance=true` \u2013 enable advanced reporting mode\n \n- `reportType=ADVANCED_NXDOMAINS` \u2013 select the NXDOMAIN breakdown report\n \n- `limit` (optional) \u2013 maximum number of host entries to return\n \n\n**Request body**\n\n- `hostQueryVolume`: object with `startDate`, `endDate`, and a `zoneNames` array\n \n- `sortFields`: maps field names (e.g., `nxdomainCount`) to `\"ASC\"` (ascending) or `\"DESC\"` (descending) to control result order\n \n\nOnce invoked, note that the response\u2019s `requestId` is stored in `reports_requestId`. Use that ID with the Reports \u201cRetrieve Report\u201d endpoint to poll for status and retrieve the completed data." - }, - "response": [] - }, - { - "name": "Zero Query Report", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "if (utils.isNotSet(pm.environment.get(\"reports_startDate\")) && utils.isNotSet(pm.environment.get(\"reports_endDate\"))) {", - " // If either value isn't set then use a default of the last 30 days", - " const reportDates = utils.lastXDays(30);", - "", - " pm.environment.set(\"reports_startDate\", reportDates[\"start\"]);", - " pm.environment.set(\"reports_endDate\", reportDates[\"end\"]);", - "}", - "", - "const requiredVariables = [\"subaccounts_accountName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"zeroZoneQueryVolume\": {\r\n \"accountName\": \"{{subaccounts_accountName}}\",\r\n \"reportStartDate\": \"{{reports_startDate}}\",\r\n \"reportEndDate\": \"{{reports_endDate}}\",\r\n \"wrap\": true\r\n }\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/reports/dns_resolution/query_volume/zone/no_queries", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "reports", - "dns_resolution", - "query_volume", - "zone", - "no_queries" - ] - }, - "description": "Retrieves a Zero\u2011Query report listing all zones under a specified account that received no DNS queries in the given date range. This call is asynchronous and returns a JSON payload containing a `requestId`, which is saved to `reports_requestId` by the collection. If you omit `reports_startDate` or `reports_endDate`, they default to the last 30 days.\n\n**Required variables**\n\n- `accountName` \u2013 the account to report on (e.g., use `subaccounts_accountName` or any accessible account)\n \n- `reports_startDate` \u2013 report start date (YYYY-MM-DD)\n \n- `reports_endDate` \u2013 report end date (YYYY-MM-DD)\n \n- `wrap` \u2013 boolean (true to wrap results in an envelope)\n \n\nOnce invoked, pass the returned `requestId` to the Reports \u201cRetrieve Report\u201d endpoint to poll for completion and retrieve the final data." - }, - "response": [] - }, - { - "name": "Retrieve Report", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"reports_requestId\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/v1/requests/{{reports_requestId}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "v1", - "requests", - "{{reports_requestId}}" - ] - }, - "description": "Retrieves the results of a previously generated report. Requires the\u202f`reports_requestId`\u202fvariable, which the collection automatically populates from the report creation response. Returns the report data payload once complete, or status and error details if still processing or failed." - }, - "response": [] - } - ], - "description": "This folder contains all endpoints for generating and fetching DNS analytics reports:\n\n- **Create a report**\n \n - `POST /reports` (or similar)\n \n - Response body includes a JSON `id` for your report\n \n - That `id` is saved automatically to `{{currentReport}}`\n \n- **Check report status & retrieve results**\n \n - `GET /reports/requests/{{currentReport}}`\n \n - Returns the current state (pending, complete, failed) and, once ready, the report data\n \n- **Notes**\n \n - The report ID lives in the `{{currentReport}}` variable by default\n \n - Running any new \u201ccreate report\u201d request will overwrite `{{currentReport}}`\u2014poll or store it elsewhere if you need multiple reports in flight simultaneously" - }, - { - "name": "Webhook", - "item": [ - { - "name": "Test Endpoint", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"username\", \"webhook_endpointUrl\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - }, - { - "listen": "test", - "script": { - "exec": [ - "// Parse the response body", - "let resp = pm.response.json();", - "", - "// Check if \"telemetryEventId\" exists in the response", - "if (resp.hasOwnProperty(\"telemetryEventId\")) {", - " // Set the \"webhook_telemetryId\" collection variable", - " pm.environment.set(\"webhook_telemetryId\", resp.telemetryEventId);", - " console.log(`Telemetry ID saved: ${resp.telemetryEventId}`);", - "} else {", - " console.error(\"Error: 'telemetryEventId' not found in the response body.\");", - "}" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"url\": \"{{webhook_endpointUrl}}\",\r\n \"type\": \"TEST_TELEMETRY_WEBHOOK\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/accounts/{{username}}/telemetryWebhook/test", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "accounts", - "{{username}}", - "telemetryWebhook", - "test" - ] - }, - "description": "Creates a test telemetry event against your configured webhook to verify connectivity.\n\n**Required variables**\n\n- `username` \u2013 the UltraDNS account name (may differ from your login username)\n \n- `webhook_endpointUrl` \u2013 the URL to receive the test event\n \n\nA post\u2011request script automatically extracts `telemetryEventId` from the JSON response and saves it to the `webhook_telemetryId` environment variable. Use that value with the Verify endpoint to confirm delivery." - }, - "response": [] - }, - { - "name": "Verify", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"username\", \"webhook_telemetryId\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{baseUrl}}/accounts/{{username}}/telemetryWebhook/test/{{webhook_telemetryId}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "accounts", - "{{username}}", - "telemetryWebhook", - "test", - "{{webhook_telemetryId}}" - ] - }, - "description": "Verifies delivery of a test telemetry event to your webhook. Requires the `username` (account name) and `webhook_telemetryId` (saved by the Test endpoint\u2019s script). Returns a JSON payload indicating success or error details." - }, - "response": [] - }, - { - "name": "Create", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"username\", \"webhook_endpointUrl\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"webhooks\": [\r\n {\r\n \"enable\": true,\r\n \"url\": \"{{webhook_endpointUrl}}\",\r\n \"include\": {\r\n \"ALL_CHANGES\": true\r\n }\r\n }\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/accounts/{{username}}/settings/PUSH_NOTIFICATIONS", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "accounts", - "{{username}}", - "settings", - "PUSH_NOTIFICATIONS" - ] - }, - "description": "Creates a push\u2011notification webhook configuration that delivers telemetry events for all account changes.\n\n**Requires:**\n\n- `username` \u2013 the UltraDNS account name\n \n- `webhook_endpointUrl` \u2013 the URL to receive live notifications\n \n\nBy default, this enables notifications for `ALL_CHANGES`. On success, returns the created webhook configuration in the response payload." - }, - "response": [] - } - ], - "description": "This folder contains all endpoints for managing UDNS push\u2011notification webhooks:\n\n- **Create Webhook** \n \n Sends your `url`, `headers`, and event filters to UDNS. (No prior validation required, but you\u2019ll typically want to test first.)\n \n- **Test Webhook** \n \n Triggers a sample telemetry event to your configured endpoint.\n \n - On success, the response body returns an `eventId`\n \n - That `eventId` is saved to `{{currentWebhookEventId}}`\n \n- **Verify Webhook Event** \n \n Polls `/webhooks/events/{{currentWebhookEventId}}` to confirm delivery status and any response details.\n \n\n**Notes:**\n\n- Replace or set `webhookUrl` and any auth headers in your environment before calling **Create Webhook**.\n \n- Running **Test Webhook** will overwrite `{{currentWebhookEventId}}`. Poll or store it elsewhere if you need to verify multiple events." - }, - { - "name": "Subaccounts", - "item": [ - { - "name": "List Subaccounts", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/subaccounts", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "subaccounts" - ] - }, - "description": "Retrieves all subaccounts under your primary UltraDNS account." - }, - "response": [] - }, - { - "name": "List Subaccounts Zones", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/subaccounts/zones", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "subaccounts", - "zones" - ] - }, - "description": "Retrieves all DNS zones across every subaccount under your primary account." - }, - "response": [] - }, - { - "name": "Subaccount Authorization", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "const requiredVariables = [\"subaccounts_accountName\"]; ", - "utils.checkVars(requiredVariables, true);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "{{baseUrl}}/subaccounts/{{subaccounts_accountName}}/token", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "subaccounts", - "{{subaccounts_accountName}}", - "token" - ] - }, - "description": "Generates a bearer token for masquerading as the specified subaccount. Requires the\u202f`subaccounts_accountName`\u202fvariable. Returns a JSON payload with new `bearerToken` and `refreshToken` scoped to that subaccount, which you can then use for subsequent subaccount\u2011scoped requests." - }, - "response": [] - } - ], - "description": "This folder contains endpoints for managing reseller\u2011style subaccounts under your primary UltraDNS account:\n\n- **List Subaccounts & Zones**\n \n - `GET /subaccounts`\n \n - Returns all subaccounts and, optionally, their zones in one call using your primary account credentials\n \n- **Masquerade as Subaccount**\n \n - `POST /subaccounts/{subaccountId}/auth`\n \n - Generates a bearer token and refresh token scoped to the specified subaccount\n \n - Use these tokens in subsequent calls to act on behalf of that subaccount\n \n\n**Usage Notes:**\n\n- All calls start with your primary account credentials.\n \n- After masquerading, switch your `{{bearerToken}}` variable to the new token to make subaccount\u2011scoped requests." - }, - { - "name": "DNSSEC Multi-Signer", - "item": [ - { - "name": "Initialize DNSSEC Settings", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"dnssecSettings\": {\r\n \"dnskeyTtl\": {{dnssec_dnskey_ttl}},\r\n \"rrsigValidity\": {{dnssec_rrsig_validity}} \r\n }\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "accounts", - "{{username}}", - "settings", - "DNSSEC_SETTINGS" - ] - }, - "description": "UltraDNS allows the configuration of some default values to be used when signing a zone. These \nconfigurations are then set for DNSSEC signing of every zone in the account:\n\n- DNSKEY TTL - The Time to Live (TTL) in seconds, used for the DNSKEY resource record set. Default value is 86400 (1 day) with valid values in the range of 300-172800 seconds (5 minutes - 2 days).\n \n- RRSIG Validity Period - Sets the RRSIG validity interval, in days when signing responses. Default value of 14 (2 weeks), with valid values in the range of 5-30 (days).\n \n\nThese default value preferences can be set using the API as shown below. Once set, these values will be used for every zone signing, rollover, and resigning action on every zone in the account.\n\nNOTE: If you have previously set these values with a call to this API then you will need to use the Update (PUT) API call to update them and the Remove (DELETE) API call to delete them." - }, - "response": [] - }, - { - "name": "Update DNSSEC Settings Copy", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"dnssecSettings\": {\r\n \"dnskeyTtl\": {{dnssec_dnskey_ttl}},\r\n \"rrsigValidity\": {{dnssec_rrsig_validity}} \r\n }\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "accounts", - "{{username}}", - "settings", - "DNSSEC_SETTINGS" - ] - }, - "description": "UltraDNS allows the configuration of some default values to be used when signing a zone. These \nconfigurations are then set for DNSSEC signing of every zone in the account:\n\n- DNSKEY TTL - The Time to Live (TTL) in seconds, used for the DNSKEY resource record set. Default value is 86400 (1 day) with valid values in the range of 300-172800 seconds (5 minutes - 2 days).\n \n- RRSIG Validity Period - Sets the RRSIG validity interval, in days when signing responses. Default value of 14 (2 weeks), with valid values in the range of 5-30 (days).\n \n\nThese default value preferences can be set using the API as shown below. Once set, these values will be used for every zone signing, rollover, and resigning action on every zone in the account.\n\nNOTE: Use the Initialize (POST) API call to initially set these values and the Remove (DELETE) API call to delete them." - }, - "response": [] - }, - { - "name": "Remove DNSSEC Settings", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "{}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "accounts", - "{{username}}", - "settings", - "DNSSEC_SETTINGS" - ] - }, - "description": "UltraDNS allows the configuration of some default values to be used when signing a zone. These \nconfigurations are then set for DNSSEC signing of every zone in the account:\n\n- DNSKEY TTL - The Time to Live (TTL) in seconds, used for the DNSKEY resource record set. Default value is 86400 (1 day) with valid values in the range of 300-172800 seconds (5 minutes - 2 days).\n \n- RRSIG Validity Period - Sets the RRSIG validity interval, in days when signing responses. Default value of 14 (2 weeks), with valid values in the range of 5-30 (days).\n \n\nThese default value preferences can be set using the API as shown below. Once set, these values will be used for every zone signing, rollover, and resigning action on every zone in the account.\n\nNOTE: Use the Initialize (POST) API call to initially set these values and the Update (PUT) API call to update them." - }, - "response": [] - }, - { - "name": "DNSSEC Sign Zone", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "dnssec" - ] - }, - "description": "This API is used to DNSSEC sign a zone on UltraDNS and can be used on both primary and secondary zones.\n\nIf you have external signer DNSKEY information you can include that as an _externalKeys_ element in the JSON payload (see [Update External Signer](https://go.postman.co/workspace/My-Workspace~44d8667f-697e-43dd-8c23-aea1d7afb89c/documentation/269716-96acc28c-c730-4484-9a15-43f2bb753d3a?entity=request-09c10a66-1e56-4e2f-8504-9f15c8dd7766)), otherwise the payload is empty." - }, - "response": [] - }, - { - "name": "DNSSEC Un-Sign Zone", - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "{}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "dnssec" - ] - }, - "description": "This API call will unsign a DNSSEC signed zone, removing all DNSKEY information (including external keys)." - }, - "response": [] - }, - { - "name": "Get DS Records", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "{}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "dnssec" - ] - }, - "description": "Provides detailed information regarding the current DNSSEC status of a zone. This API call can be used to get the DS (Designated Signer) records for the zone that can be used by the parent zone to establish a chain-of-trust for the zone." - }, - "response": [] - }, - { - "name": "Update External Signer", - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"externalKeys\":[\r\n {\r\n \"ksk\":[\"{{dnssec_extkey_ksk}}\"],\r\n \"zsk\":[\"{{dnssec_extkey_zsk}}\"]\r\n }\r\n ]\r\n} ", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "dnssec" - ] - }, - "description": "Configure external signer keys (KSK and ZSK) for a DNSSEC signed zone. KSK and ZSK DNSKEY records are formatted as follows:\n\n```\n \n\n ```\n\nNOTE: For an unsigned zone you can change the method to POST and set the value of _externalKeys_ to both DNSSEC sign a zone and install the DNSKEY records from an external provider." - }, - "response": [] - }, - { - "name": "Remove External Signer", - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"externalKeys\":[]\r\n} ", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "dnssec" - ] - }, - "description": "Remove DNSKEY records for external signer from a DNSSEC signed zone.\n\nNOTE: External keys will not show up in the UltraDNS portal. Run a _dig_ command against the zone for DNSKEY records to verify the external keys were added. For example:\n\n_\\>> dig @udns1.ultradns.com example.com DNSKEY_" - }, - "response": [] - } - ], - "description": "UltraDNS API endpoints that support [multi-signer DNSSEC](https://ultra-portalstatic.ultradns.com/static/console/docs/DNSSEC-Multi_Signer-Guide.pdf).\n\nUltraDNS DNSSEC uses _online_ (also known as _on-the-fly_) signing in generating signed responses to queries. UltraDNS supports DNSSEC algorithm 13 only for this process. Implementers of multi-signer can add DNSKEY details for external signers using other algorithms as needed, but all UltraDNS generated key information uses algorithm 13 (ECDSA).\n\nAdditionally, UltraDNS signers generate a unique KSK and ZSK for every zone. This approach gives flexibility for zone owners to roll their KSK without impacting other zones that share the KSK information and allows the ZSK to be automatically rolled at regular intervals. The implementation of multi-signer follows the methods described in [RFC 8901 model 2](https://www.rfc-editor.org/rfc/rfc8901.html#name-model-2-unique-ksk-set-and-) where each signer maintains its own unique KSK and ZSK.\n\nSupport of DNSSEC Multi-Signer is derived from, and supports portions of the following RFCs:\n\n- [RFC 8901](https://www.rfc-editor.org/rfc/rfc8901.html) - Multi-Signer DNSSEC Models.\n \n- [RFC 7344](https://www.rfc-editor.org/rfc/rfc7344) - Automating DNSSEC Delegation Trust Maintenance.\n \n- [RFC 8078](https://www.rfc-editor.org/rfc/rfc8078) - Managing DS Records from the Parent via CDS/CDNSKEY.\n \n- [RFC 6781](https://www.rfc-editor.org/rfc/rfc6781.html) - DNSSEC Operational Practices, Version 2." - }, - { - "name": "Traffic Management", - "item": [ - { - "name": "SiteBacker", - "item": [ - { - "name": "Record Priority Update", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Content-Type", - "value": "application/json-patch+json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "[\r\n // JSON DTO (pool record with lowest value for priority field.\r\n {\r\n \"op\": \"replace\",\r\n \"path\": \"/profile/rdataInfo/0/priority\",\r\n \"value\": \"101\"\r\n },\r\n // JSON DTO (pool record with the next highest value for priority field.\r\n {\r\n \"op\": \"replace\",\r\n \"path\": \"/profile/rdataInfo/1/priority\",\r\n \"value\": \"1\"\r\n }\r\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/rrsets/{{sb_rrType}}/{{sb_ownerName}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "rrsets", - "{{sb_rrType}}", - "{{sb_ownerName}}" - ] - }, - "description": "**Overview** \n \nUpdates the failover/load\u2011order priority of a single member in a SiteBacker pool. The member is selected by its index in the pool\u2019s member list (the \u201cpath\u201d parameter):\n\n- **Index 0** targets the first (lowest\u2011priority) record\n \n- **Index 1** targets the second record\n \n- And so on for larger pools\n \n\nChanging the member\u2019s `priority` value determines its position in the failover or load\u2011balancing sequence.\n\n**Usage Notes**\n\n- In a simple two\u2011member pool (e.g. priorities 1 and 101), you can swap their roles by PATCHing each index without altering the request body.\n \n- For pools with more than two members, adjust each member\u2019s `priority` to reflect the exact ordering you need." - }, - "response": [] - }, - { - "name": "Create SiteBacker Pool", - "event": [ - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"ttl\": 300,\r\n \"rdata\": [\r\n \"1.1.1.1\",\r\n \"2.2.2.2\",\r\n \"3.3.3.3\",\r\n \"4.4.4.4\"\r\n ],\r\n \"profile\": {\r\n \"@context\": \"http://schemas.ultradns.com/SBPool.jsonschema\",\r\n \"description\": \"Test SiteBacker Pool\",\r\n \"runProbes\": true,\r\n \"actOnProbes\": true,\r\n \"order\": \"FIXED\",\r\n \"maxActive\": 1,\r\n \"failureThreshold\": 0,\r\n \"maxServed\": 1,\r\n \"rdataInfo\": [{\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }],\r\n \"backupRecords\": [{\r\n \"rdata\": \"9.9.9.9\",\r\n \"failoverDelay\":0\r\n }]\r\n }\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/rrsets/{{sb_rrType}}/{{sb_ownerName}}", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "zones", - "{{zones_zoneName}}", - "rrsets", - "{{sb_rrType}}", - "{{sb_ownerName}}" - ] - }, - "description": "**Overview** \n \nCreates a new SiteBacker pool under the specified zone and record owner. The request body must include:\n\n- **rdata**: an array of IP addresses to include in the pool\n \n- **rdataInfo**: one object per IP with:\n \n - `state` (NORMAL,\u202fFORCE_ACTIVE,\u202fFORCE_FAIL)\n \n - `runProbes` (true\u202f/\u202ffalse)\n \n - `priority` (positive integer)\n \n - `failoverDelay` (0 or positive integer)\n \n - `threshold` (positive integer)\n \n - `availableToServe` (true\u202f/\u202ffalse)\n \n- **backupRecords**: an array of fallback records, each with:\n \n - `rdata` (IP address)\n \n - `failoverDelay` (0 or positive integer)" - }, - "response": [] - } - ], - "description": "This folder contains endpoints for managing SiteBacker pools\u2014a traffic\u2011management feature that groups multiple IPs under one DNS record and uses health\u2011check probes to steer queries based on endpoint health and defined priorities.\n\n- **Create Pool**: provision a new pool of endpoints for a given zone/record, complete with probe settings and failover rules\n \n- **Update Member Priority**: reorder pool members to control failover order" - } - ], - "description": "This folder groups UltraDNS\u2019s advanced traffic\u2011management features, each in its own subfolder:\n\n- **SiteBacker**: configure health\u2011check probes that monitor endpoints and automatically steer traffic away from failures\n \n- **Direction**: set up geography\u2011aware routing so queries resolve to the closest or best\u2011suited data center\n \n- **Traffic Controller**: create load\u2011balancing rules to distribute DNS traffic across multiple targets based on weight, priority, or custom logic\n \n- **\\[Other advanced services\\]**: each subfolder covers a specific traffic\u2011management API for steering, failover, and performance optimization\n \n\nUse these endpoints to build resilient, geo\u2011intelligent DNS strategies that adapt in real time to health, location, and load." - } - ], - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{accessToken}}", - "type": "string" - } - ] - }, - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "if (!pm.environment.name) {", - " throw new Error(\"MissingEnvironment: No environment selected. Please select an environment before running the request.\");", - "}", - "", - "utils = {", - " isNotSet: function(val) {", - " const empty = [null, undefined, \"\", \"null\", \"undefined\"];", - " const placeholders = [\"HASH\", \"PASSWORD\", \"UNIX_TIMESTAMP\", \"GUID\"];", - " return empty.includes(val) || placeholders.includes(val);", - " },", - " checkVars: function(values, checkEnv=false) {", - " values.forEach((varName) => {", - " let value, errorType;", - " if (checkEnv) {", - " value = pm.environment.get(varName);", - " errorType = \"MissingEnvironmentVariable\";", - " } else {", - " value = pm.collectionVariables.get(varName);", - " errorType = \"MissingCollectionVariable\";", - " }", - " if (utils.isNotSet(value)) {", - " throw new Error(`${errorType}: The variable \"${varName}\" is not set or is null. Please set a valid value before proceeding.`);", - " }", - " });", - " },", - " lastXDays: function(days) {", - " if (days > 30) {", - " throw new Error(`You specified ${days.toString()} days but the max is 30.`);", - " }", - " const yesterday = new Date();", - " yesterday.setDate(yesterday.getDate() - 1);", - " const startDate = new Date();", - " startDate.setDate(yesterday.getDate() - days);", - " return {", - " \"start\": startDate.toISOString().split('T')[0],", - " \"end\": yesterday.toISOString().split('T')[0]", - " }", - " }", - "};", - "", - "utils.checkVars([\"username\", \"password\"], true);", - "", - "const username = pm.environment.get(\"username\");", - "const password = pm.environment.get(\"password\");", - "", - "utils.checkVars([\"baseUrl\"]);", - "const baseUrl = pm.collectionVariables.get('baseUrl');", - "", - "const currentAccessToken = pm.environment.get('accessToken');", - "const currentRefreshToken = pm.environment.get('refreshToken');", - "const tokenTimestamp = pm.environment.get('tokenTimestamp');", - "", - "function setTokens(accessToken, refreshToken) {", - " const now = Date.now();", - " pm.environment.set('accessToken', accessToken);", - " pm.environment.set('refreshToken', refreshToken);", - " pm.environment.set('tokenTimestamp', now.toString());", - "}", - "", - "function getNewTokens(un, pw) {", - " const payload = {", - " grant_type: 'password',", - " username: un,", - " password: pw", - " };", - "", - " pm.sendRequest({", - " url: `${baseUrl}/authorization/token`,", - " method: 'POST',", - " header: 'Content-Type:application/x-www-form-urlencoded',", - " body: {", - " mode: 'urlencoded',", - " urlencoded: Object.keys(payload).map(key => ({key, value: payload[key]}))", - " }", - " }, (err, res) => {", - " if (err) {", - " console.error(`AuthFailed: ${err}`);", - " } else {", - " setTokens(res.json().accessToken, res.json().refreshToken);", - " }", - " });", - "}", - "", - "if (utils.isNotSet(currentAccessToken) || utils.isNotSet(tokenTimestamp)) {", - " getNewTokens(username, password);", - "} else {", - " const fiftyFiveMinutes = 55 * 60 * 1000; // milliseconds", - " const now = Date.now();", - " const timePassed = now - parseInt(tokenTimestamp, 10);", - "", - " // If more than 55min has passed, we try to refresh the token", - " if (timePassed > fiftyFiveMinutes) {", - " if (currentRefreshToken) {", - " const payload = {", - " grant_type: 'refresh_token',", - " refresh_token: currentRefreshToken", - " };", - "", - " pm.sendRequest({", - " url: `${baseUrl}/authorization/token`,", - " method: 'POST',", - " header: 'Content-Type:application/x-www-form-urlencoded',", - " body: {", - " mode: 'urlencoded',", - " urlencoded: Object.keys(payload).map(key => ({key, value: payload[key]}))", - " }", - " }, (err, res) => {", - " if (err || res.code !== 200) {", - " // If there's an error or the refresh token is stale", - " console.log(`RefreshFailed: Bad refresh token, re-authenticating: ${err}`)", - " getNewTokens(username, password);", - " } else {", - " setTokens(res.json().accessToken, res.json().refreshToken);", - " }", - " });", - " } else {", - " getNewTokens(username, password);", - " }", - " }", - "}" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "// Check if the x-task-id header is present in the response", - "let taskId = pm.response.headers.get(\"x-task-id\");", - "", - "if (taskId) {", - " pm.environment.set(\"currentTask\", taskId);", - " console.log(`Saved x-task-id: ${taskId} to currentTask collection variable.`);", - "}", - "", - "// Check if there's a response body and if the response can be parsed as JSON", - "if (pm.response.text() && pm.response.headers.get('Content-Type').includes('application/json')) {", - " try {", - " let resp = pm.response.json();", - " ", - " // Check if \"requestId\" exists in the response", - " if (resp.hasOwnProperty(\"requestId\")) {", - " // Set the \"requestId\" collection variable", - " pm.environment.set(\"reports_requestId\", resp.requestId);", - " console.log(`Request ID saved: ${resp.requestId}`);", - " }", - " } catch (e) {", - " // This will catch any errors in parsing the JSON, but do nothing", - " // Just in case, so it doesn't somehow cause non-JSON responses to error", - " }", - "}", - "" - ] - } - } - ], - "variable": [ - { - "key": "baseUrl", - "value": "https://api.ultradns.com", - "type": "string" - } - ] + "info": { + "_postman_id": "29e85d3c-6aff-4e7d-8c7c-26778846f0d4", + "name": "API Documentation v1.0.0", + "description": "This Postman collection provides a sample interface to the UltraDNS (UDNS) REST API. It’s organized around resource‑focused folders:\n\n- **Zones**: create, read, update, and delete DNS zones and records\n \n- **Reports**: retrieve usage statistics and analytics\n \n- **…other resources**: each top‑level or subfolder groups related endpoints\n \n\nA global pre‑request script handles authentication and common helpers:\n\n1. **Reads** your `username` and `password` from the selected environment\n \n2. **Requests** a bearer token and saves it to `{{bearerToken}}`\n \n3. **Automatically refreshes** the token when it expires\n \n4. **Exposes** utility functions on the `utils` object\n \n\n**Setup before running:**\n\n1. Select the appropriate Postman environment.\n \n2. Define `username` and `password` as environment variables.\n \n\n**Using helpers:**\n\n``` js\n// call any helper in scripts or tests\nutils.functionName(arg1, arg2)\n\n ```\n\nWith this in place, every folder and request can focus on its specific API logic, while authentication and shared utilities stay centralized.", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "2146434" + }, + "item": [ + { + "name": "Zones", + "item": [ + { + "name": "List Zones", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones" + ] + }, + "description": "Retrieves all DNS zones in your account. The response returns an array of zone objects, each including details such as zone name, status, default TTL, and name servers." + }, + "response": [ + { + "name": "List Zones", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:49:15 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "270" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"queryInfo\": {\n \"q\": \"\",\n \"sort\": \"name\",\n \"reverse\": false,\n \"limit\": 100\n },\n \"cursorInfo\": {},\n \"zones\": [\n {\n \"properties\": {\n \"name\": \"domain.com.\",\n \"accountName\": \"postman-example\",\n \"type\": \"PRIMARY\",\n \"dnssecStatus\": \"UNSIGNED\",\n \"status\": \"ACTIVE\",\n \"owner\": \"postman-example\",\n \"resourceRecordCount\": 7,\n \"lastModifiedDateTime\": \"2025-06-17T23:48Z\",\n \"ultra2\": false\n }\n },\n {\n \"properties\": {\n \"name\": \"postman-example.xyz.\",\n \"accountName\": \"postman-example\",\n \"type\": \"PRIMARY\",\n \"dnssecStatus\": \"UNSIGNED\",\n \"status\": \"ACTIVE\",\n \"owner\": \"postman-example\",\n \"resourceRecordCount\": 7,\n \"lastModifiedDateTime\": \"2025-06-17T23:43Z\",\n \"ultra2\": false\n }\n }\n ]\n}" + } + ] + }, + { + "name": "List Zone Properties", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones/{{zones_zoneName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "{{zones_zoneName}}" + ] + }, + "description": "Retrieves metadata for a specific DNS zone, including record count, name servers, status, type, and other zone‑level properties. Requires the `zones_zoneName` path variable." + }, + "response": [ + { + "name": "List Zone Properties", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones/{{zones_zoneName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "{{zones_zoneName}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:48:57 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"properties\": {\n \"name\": \"domain.com.\",\n \"accountName\": \"postman-example\",\n \"type\": \"PRIMARY\",\n \"dnssecStatus\": \"UNSIGNED\",\n \"status\": \"ACTIVE\",\n \"owner\": \"postman-example\",\n \"resourceRecordCount\": 7,\n \"lastModifiedDateTime\": \"2025-06-17T23:48Z\"\n },\n \"registrarInfo\": {\n \"nameServers\": {\n \"missing\": [\n \"pdns1.ultradns.net.\",\n \"pdns2.ultradns.net.\",\n \"pdns3.ultradns.org.\",\n \"pdns4.ultradns.org.\",\n \"pdns5.ultradns.info.\",\n \"pdns6.ultradns.co.uk.\"\n ]\n }\n },\n \"inherit\": \"ALL\"\n}" + } + ] + }, + { + "name": "Create Zone", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"username\",\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"properties\":{\n \"name\":\"{{zones_zoneName}}\",\n \"accountName\":\"{{username}}\",\n \"type\":\"PRIMARY\"\n },\n \"primaryCreateInfo\":{\n \"forceImport\":true,\n \"createType\":\"NEW\"\n },\n \"changeComment\":\"Create zone as agreed\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v3/zones", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones" + ] + }, + "description": "Creates a new DNS zone. The request body must include:\n\n- **properties.name**: zones_zoneName (the name of the new zone)\n \n- **properties.accountName**: username (your UltraDNS account)\n \n- **properties.type**: PRIMARY\n \n- **primaryCreateInfo.forceImport**: true or false\n \n- **primaryCreateInfo.createType**: NEW or IMPORT\n \n- **changeComment**: free‑form text describing why the zone is being created\n \n\nMake sure the environment variables zones_zoneName and username are set before running this request." + }, + "response": [ + { + "name": "Create Zone", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"properties\":{\n \"name\":\"{{zones_zoneName}}\",\n \"accountName\":\"{{username}}\",\n \"type\":\"PRIMARY\"\n },\n \"primaryCreateInfo\":{\n \"forceImport\":true,\n \"createType\":\"NEW\"\n },\n \"changeComment\":\"Create zone as agreed\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v3/zones", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:48:11 GMT" + }, + { + "key": "Location", + "value": "http://api.ultradns.com/v3/zones/domain.com." + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "42" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "List Zone Web Forwards", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones/{{zones_zoneName}}/webforwards", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "{{zones_zoneName}}", + "webforwards" + ] + }, + "description": "Retrieves all web‑forward rules configured for a specific DNS zone. Requires the `zone_zoneName` environment variable. The response returns an array of web‑forward objects, each including fields such as:\n\n- `guid` (the forward’s unique ID)\n \n- `requestTo` (the hostname being forwarded)\n \n- `defaultRedirectTo` (the target URL)\n \n- `defaultForwardType` (301, 302, etc.)" + }, + "response": [ + { + "name": "List Zone Web Forwards", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones/{{zones_zoneName}}/webforwards", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "{{zones_zoneName}}", + "webforwards" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:50:27 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "228" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"queryInfo\": {\n \"sort\": \"REQUEST_TO\",\n \"reverse\": false,\n \"limit\": 100\n },\n \"resultInfo\": {\n \"totalCount\": 1,\n \"offset\": 0,\n \"returnedCount\": 1\n },\n \"webForwards\": [\n {\n \"guid\": \"9034F201636B98D9\",\n \"requestTo\": \"www.domain.com\",\n \"defaultRedirectTo\": \"https://www.example.com\",\n \"defaultForwardType\": \"HTTP_301_REDIRECT\"\n }\n ]\n}" + } + ] + }, + { + "name": "Initiate Zone(s) Export", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"zoneNames\": [\n \"{{zones_zoneName}}\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v3/zones/export", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "export" + ] + }, + "description": "Initiates an export job for the specified DNS zone. Requires the `zones_zoneName` environment variable.\n\nOn success, returns **202 Accepted** with an `x-task-id` header containing the export job ID. Use the Task endpoints to poll for status and retrieve the exported zone file." + }, + "response": [ + { + "name": "Initiate Zone(s) Export", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"zoneNames\": [\n \"{{zones_zoneName}}\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v3/zones/export", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "export" + ] + } + }, + "status": "Accepted", + "code": 202, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:50:35 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Task-Id", + "value": "7c59fe98-1451-4f4a-8195-ed6690792a90" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Pending\"\n}" + } + ] + }, + { + "name": "Create Snapshot", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v1/zones/{{zones_zoneName}}/snapshot", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "zones", + "{{zones_zoneName}}", + "snapshot" + ] + }, + "description": "Creates a point‑in‑time snapshot of the specified DNS zone, replacing any existing snapshot. Requires the `zones_zoneName` environment variable.\n\n- On success, returns **202 Accepted** with an `x-task-id` header containing the snapshot job ID\n \n- Use the Task endpoints to poll for status and confirm completion before attempting to restore or export the snapshot" + }, + "response": [ + { + "name": "Create Snapshot", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v1/zones/{{zones_zoneName}}/snapshot", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "zones", + "{{zones_zoneName}}", + "snapshot" + ] + } + }, + "status": "Accepted", + "code": 202, + "_postman_previewlanguage": "plain", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:50:49 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Task-Id", + "value": "2df0aa54-cc3a-4724-943d-eb33c302cf2a" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "0" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": null + } + ] + }, + { + "name": "Restore Snapshot", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v1/zones/{{zones_zoneName}}/restore", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "zones", + "{{zones_zoneName}}", + "restore" + ] + }, + "description": "Restores the specified DNS zone to its most recent snapshot, overwriting the current configuration. This action is **destructive and irreversible**. Requires the `zones_zoneName` environment variable.\n\nOn success, returns **202 Accepted** with an `x-task-id` header containing the restore job ID. Use the Task endpoints to poll for status and confirm completion." + }, + "response": [ + { + "name": "Restore Snapshot", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v1/zones/{{zones_zoneName}}/restore", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "zones", + "{{zones_zoneName}}", + "restore" + ] + } + }, + "status": "Accepted", + "code": 202, + "_postman_previewlanguage": "plain", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:51:03 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Task-Id", + "value": "7418858e-f915-44cb-ae54-a56cb37cb99b" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "0" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": null + } + ] + }, + { + "name": "Request Zone Transfer", + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "https://api.ultradns.com/zones/{{zones_zoneName}}/transfer", + "protocol": "https", + "host": [ + "api", + "ultradns", + "com" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "transfer" + ] + }, + "description": "Requests a synchronization of the specified secondary DNS zone. Requires the `zones_zoneName` environment variable.\n\nOn success, returns **200 OK**. You can verify the transfer by fetching the zone details and checking the serial or record changes." + }, + "response": [ + { + "name": "Request Zone Transfer", + "originalRequest": { + "method": "POST", + "header": [], + "url": { + "raw": "https://api.ultradns.com/zones/{{zones_zoneName}}/transfer", + "protocol": "https", + "host": [ + "api", + "ultradns", + "com" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "transfer" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:47:34 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + } + ], + "description": "This folder contains all operations for managing the lifecycle and metadata of your DNS zones. Use these endpoints to:\n\n- **Create** new zones\n \n- **Retrieve** zone details and metadata\n \n- **Update** zone configuration\n \n- **Delete** existing zones\n \n- **Export** zone files\n \n- **Capture** zone snapshots\n \n\nEverything here is focused on DNS zone management and its associated metadata.", + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "Records", + "item": [ + { + "name": "List RRsets", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "var query_params = {\r", + " // Query will look something like this: q=ttl:300+kind:RECORDS. Potential values:\r", + " // * ttl:String (number >= 0. Only valid for kind=RECORDS)\r", + " // * owner:String (partial match of owner name)\r", + " // * value:String (partial match of rdata, RECORDS kind only)\r", + " // * kind:ALL|RECORDS|POOLS|RD_POOLS|DIR_POOLS|SB_POOLS|TC_POOLS\r", + " // This value for q will query for all regular records with TTL of 300 and owner name containing \"www\":\r", + " //'q': 'ttl:300+kind:RECORDS+owner:www',\r", + " //'offset': '0',\r", + " //'limit': '100',\r", + " //'sort': 'OWNER',\r", + " //'reverse': 'false',\r", + " //'systemGeneratedStatus': 'true',\r", + "}\r", + "\r", + "for (let key in query_params) {\r", + " console.log(key, query_params[key])\r", + " pm.request.url.query.add({key: key, value: query_params[key]})\r", + "}" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets" + ] + }, + "description": "Retrieves all resource record sets (RRSets) in the specified DNS zone. Requires the `records_zoneName` environment variable.\n\nSupports optional query parameters to filter results (for example, by record type, ownerName, TTL) or paginate the list." + }, + "response": [ + { + "name": "List RRsets", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:52:04 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "301" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"zoneName\": \"domain.com\",\n \"rrSets\": [\n {\n \"ownerName\": \"domain.com.\",\n \"rrtype\": \"NS (2)\",\n \"ttl\": 86400,\n \"rdata\": [\n \"pdns1.ultradns.net.\",\n \"pdns2.ultradns.net.\",\n \"pdns3.ultradns.org.\",\n \"pdns4.ultradns.org.\",\n \"pdns5.ultradns.info.\",\n \"pdns6.ultradns.co.uk.\"\n ]\n },\n {\n \"ownerName\": \"domain.com.\",\n \"rrtype\": \"SOA (6)\",\n \"ttl\": 86400,\n \"rdata\": [\n \"pdns1.ultradns.net. shane\\\\.barbetta.digicert.com. 2025061702 86400 86400 86400 86400\"\n ]\n },\n {\n \"ownerName\": \"www.domain.com.\",\n \"rrtype\": \"A (1)\",\n \"ttl\": 300,\n \"rdata\": [\n \"204.74.99.100\"\n ]\n }\n ],\n \"queryInfo\": {\n \"sort\": \"OWNER\",\n \"reverse\": false,\n \"limit\": 100\n },\n \"resultInfo\": {\n \"totalCount\": 3,\n \"offset\": 0,\n \"returnedCount\": 3\n }\n}" + } + ] + }, + { + "name": "List Records by Type", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "var query_params = {\r", + " // Query will look something like this: q=ttl:300+kind:RECORDS. Potential values:\r", + " // * ttl:String (number >= 0. Only valid for kind=RECORDS)\r", + " // * owner:String (partial match of owner name)\r", + " // * value:String (partial match of rdata, RECORDS kind only)\r", + " // * kind:ALL|RECORDS|POOLS|RD_POOLS|DIR_POOLS|SB_POOLS|TC_POOLS\r", + " // This value for q will query for all regular records with TTL of 300 and owner name containing \"www\":\r", + " //'q': 'ttl:300+kind:RECORDS+owner:www',\r", + " //'offset': '0',\r", + " //'limit': '100',\r", + " //'sort': 'OWNER',\r", + " //'reverse': 'false',\r", + " //'systemGeneratedStatus': 'true',\r", + "}\r", + "\r", + "for (let key in query_params) {\r", + " console.log(key, query_params[key])\r", + " pm.request.url.query.add({key: key, value: query_params[key]})\r", + "}" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}" + ] + }, + "description": "Retrieves all resource record sets (RRSets) of a specific type within the specified DNS zone. Requires the `records_zoneName` and `records_type` environment variables. Set `records_type` to the desired record type (e.g., A, CNAME, TXT) to filter the results. The response returns an array of matching RRSet objects." + }, + "response": [ + { + "name": "List Records by Type", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:52:27 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"zoneName\": \"domain.com\",\n \"rrSets\": [\n {\n \"ownerName\": \"www.domain.com.\",\n \"rrtype\": \"A (1)\",\n \"ttl\": 300,\n \"rdata\": [\n \"204.74.99.100\"\n ]\n }\n ],\n \"queryInfo\": {\n \"sort\": \"OWNER\",\n \"reverse\": false,\n \"limit\": 100\n },\n \"resultInfo\": {\n \"totalCount\": 1,\n \"offset\": 0,\n \"returnedCount\": 1\n }\n}" + } + ] + }, + { + "name": "List Pools", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones/{{records_zoneName}}/rrsets?q=kind:POOLS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "{{records_zoneName}}", + "rrsets" + ], + "query": [ + { + "key": "q", + "value": "kind:POOLS" + } + ] + }, + "description": "Retrieves all traffic‑management pools (RRSets configured for advanced DNS features) in the specified DNS zone. Requires the `records_zoneName` environment variable. The response returns an array of pool RRSet objects, each including its pool-specific metadata." + }, + "response": [ + { + "name": "List Pools", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v3/zones/{{records_zoneName}}/rrsets?q=kind:POOLS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v3", + "zones", + "{{records_zoneName}}", + "rrsets" + ], + "query": [ + { + "key": "q", + "value": "kind:POOLS" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:53:55 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"zoneName\": \"domain.com\",\n \"rrSets\": [\n {\n \"ownerName\": \"pool.domain.com.\",\n \"rrtype\": \"A (1)\",\n \"rdata\": [\n \"192.168.1.1\"\n ],\n \"profile\": {\n \"@context\": \"http://schemas.ultradns.com/DirPool.jsonschema\",\n \"description\": \"pool\",\n \"rdataInfo\": [\n {\n \"allNonConfigured\": true,\n \"ttl\": 86400,\n \"type\": \"A\"\n }\n ]\n }\n }\n ],\n \"queryInfo\": {\n \"q\": \"kind:POOLS\",\n \"sort\": \"OWNER\",\n \"reverse\": false,\n \"limit\": 100\n },\n \"resultInfo\": {\n \"totalCount\": 1,\n \"offset\": 0,\n \"returnedCount\": 1\n }\n}" + } + ] + }, + { + "name": "Create RRset", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// Variables to control record creation. This is much easier than switching back and forth\r", + "// to the environment in order to update these parameters: \r", + "//\r", + "// * TODO: Specify values for ownerName, recordType, recordTtl, and recordRdata\r", + "\r", + "const ownerName = '{{records_ownerName}}';\r", + "const recordType = '{{records_type}}';\r", + "const recordTtl = '300';\r", + "\r", + "// Examples of recordRdata:\r", + "// * A: 1.1.1.1\r", + "// * CNAME: www.example.com\r", + "// * MX: 10 mail.example.com\r", + "// * MX (NULL): 0 .\r", + "\r", + "const recordRdata = '1.1.1.1';\r", + "\r", + "const bodyContent = {\r", + " 'ttl': recordTtl,\r", + " 'rdata': [\r", + " recordRdata\r", + " ]\r", + "}\r", + "\r", + "// Convert the JavaScript object to a JSON string\r", + "const bodyContentString = JSON.stringify(bodyContent);\r", + "\r", + "// Set the environment variable with the JSON string\r", + "pm.environment.set(\"requestBody\", bodyContentString);\r", + "\r", + "// Update environment variables to reflect record being configured\r", + "//pm.environment.set('records_ownerName', ownerName);\r", + "//pm.environment.set('records_type', recordType);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestBody}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}", + "{{records_ownerName}}" + ] + }, + "description": "Creates a new resource record set (RRSet) in the specified DNS zone.\n\n- **Required variables:**\n \n - `records_zoneName` – target DNS zone\n \n - `records_ownerName` – owner name (record label)\n \n - `records_type` – record type (A, CNAME, MX, etc.)\n \n- **Body construction:** \n A pre‑request script reads these environment vars plus:\n \n - `recordTtl` (default “300”)\n \n - `recordRdata` (e.g. “1.1.1.1” for A records) \n It builds an object (`{ ttl: recordTtl, rdata: [ recordRdata ] }`), stringifies it, and sets it to the `requestBody` environment variable." + }, + "response": [ + { + "name": "Create RRset", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestBody}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}", + "{{records_ownerName}}" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:54:23 GMT" + }, + { + "key": "Location", + "value": "http://api.ultradns.com/zones/domain.com/rrsets/A/rrset-create" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "Delete RRset", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "if (pm.response.code == '204') {\r", + " console.log(\"Delete happened immediately!\");\r", + "} else if (pm.response.code == '202') {\r", + " console.log(\"Delete happened in background!\");\r", + " console.log(\"X-Task-ID: \" + pm.response.headers.get('X-Task-ID'));\r", + "} else {\r", + " console.log(\"Delete Response (status code == \" + pm.response.code + \")!\");\r", + "}" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "//pm.environment.set('records_type', 'A');\r", + "//pm.environment.set('records_ownerName', '');" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}", + "{{records_ownerName}}" + ] + }, + "description": "Deletes the specified resource record set (RRSet) from the given DNS zone.\n\n- **Required variables:**\n \n - records_zoneName – the DNS zone containing the RRSet\n \n - records_ownerName – the owner name (record label) of the RRSet\n \n - records_type – the record type (A, CNAME, TXT, etc.)" + }, + "response": [ + { + "name": "Delete RRset", + "originalRequest": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}", + "{{records_ownerName}}" + ] + } + }, + "status": "No Content", + "code": 204, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:56:08 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": null + } + ] + }, + { + "name": "Update RRset", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "if (pm.response.code == '200') {\r", + " console.log(\"Update happened immediately!\");\r", + "} else if (pm.response.code == '202') {\r", + " console.log(\"Update happened in background!\");\r", + " console.log(\"X-Task-ID: \" + pm.response.headers.get('X-Task-ID'));\r", + "} else {\r", + " console.log(\"Update Response (status code == \" + pm.response.code + \")!\");\r", + "}" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "// NOTE: You must provide ALL record information. \r", + "// Any resource records not included will be removed from the RRSet.\r", + "// It is recommended that you call \"List RRset\" first to get an RRset DTO that you\r", + "// can modify and then send to this \"Update RRset\" API.\r", + "// \r", + "// Variables to control record update. This is much easier than switching back and forth\r", + "// to the environment in order to update these parameters: \r", + "//\r", + "// * TODO: Specify values for ownerName, recordType, recordTtl, and recordRdata\r", + "\r", + "const ownerName = '{{records_ownerName}}';\r", + "const recordType = '{{records_type}}';\r", + "const recordTtl = '300';\r", + "\r", + "// Examples of recordRdata:\r", + "// * A: 1.1.1.1\r", + "// * CNAME: www.example.com\r", + "// * MX: 10 mail.example.com\r", + "// * MX (NULL): 0 .\r", + "\r", + "const recordRdata = '1.1.1.1';\r", + "\r", + "const bodyContent = {\r", + " 'ttl': recordTtl,\r", + " 'rdata': [\r", + " recordRdata\r", + " ]\r", + "}\r", + "\r", + "// Convert the JavaScript object to a JSON string\r", + "const bodyContentString = JSON.stringify(bodyContent);\r", + "\r", + "// Set the environment variable with the JSON string\r", + "pm.environment.set(\"requestBody\", bodyContentString);\r", + "\r", + "// Update environment variables to reflect record being configured\r", + "//pm.environment.set('records_ownerName', ownerName);\r", + "//pm.environment.set('records_type', recordType);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestBody}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}", + "{{records_ownerName}}" + ] + }, + "description": "Updates an existing resource record set (RRSet) in the specified DNS zone.\n\n- **Required variables:**\n \n - records_zoneName – the DNS zone containing the RRSet\n \n - records_ownerName – the owner name (record label) of the RRSet\n \n - records_type – the record type (A, CNAME, MX, etc.)\n \n- **Body construction:**\n \n A pre-request script builds the `requestBody` object with your `recordTtl` and `recordRdata`, stringifies it, and sets it to the `requestBody` environment variable. Any records not included in this body will be removed from the RRSet." + }, + "response": [ + { + "name": "Update RRset", + "originalRequest": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{{requestBody}}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{records_zoneName}}/rrsets/{{records_type}}/{{records_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{records_zoneName}}", + "rrsets", + "{{records_type}}", + "{{records_ownerName}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:54:50 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + } + ], + "description": "This folder includes all endpoints for managing resource record sets (RRSets) within a DNS zone. Each RRSet groups records sharing the same owner name, type, and class (always IN). Record data is handled via the `rdata` array, which follows the BIND presentation format.\n\nUse these endpoints to:\n\n- **List** all RRSets in a zone\n \n- **Retrieve** a specific RRSet by owner name and type\n \n- **Create/Update** RRSets by supplying `rdata` entries and TTL\n \n- **Delete** RRSets\n \n\nPre‑request scripts in this folder help initialize variables like `zoneName`, `ownerName`, and `recordType`. Run these scripts or set the corresponding environment variables before making calls." + }, + { + "name": "Tasks", + "item": [ + { + "name": "Check Task", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"currentTask\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/tasks/{{currentTask}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "tasks", + "{{currentTask}}" + ] + }, + "description": "Checks the status of a background task. Requires the `currentTask` variable, which the collection automatically populates from the x-task-id header of previous async operations." + }, + "response": [ + { + "name": "Check Task", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/tasks/{{currentTask}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "tasks", + "{{currentTask}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:57:42 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"taskId\": \"605b23e4-edb9-4f23-ae2d-33fe24d6033f\",\n \"code\": \"COMPLETE\",\n \"message\": \"domain.com. export completed.\",\n \"resultUri\": \"/tasks/605b23e4-edb9-4f23-ae2d-33fe24d6033f/result\",\n \"hasData\": true\n}" + } + ] + }, + { + "name": "Task Result", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"currentTask\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/tasks/{{currentTask}}/result", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "tasks", + "{{currentTask}}", + "result" + ] + }, + "description": "Retrieves the final result of a completed background task. Requires the `currentTask` variable, which the collection automatically populates from the x-task-id header of prior async requests. Returns the task’s result payload when finished." + }, + "response": [ + { + "name": "Task Result", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/tasks/{{currentTask}}/result", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "tasks", + "{{currentTask}}", + "result" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "plain", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Expose-Headers", + "value": "Content-Disposition" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Disposition", + "value": "inline;filename=\"605b23e4-edb9-4f23-ae2d-33fe24d6033f.txt\"" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "text/plain" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:57:51 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "258" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": ";File created: 06/17/2025 23:57\r\n;Record count: 8\r\n$ORIGIN domain.com.\r\n@\t86400\tIN\tSOA pdns1.ultradns.net. shane\\.barbetta.digicert.com. (\r\n\t\t\t2025061707\t;Serial\r\n\t\t\t86400\t\t;Refresh\r\n\t\t\t86400\t\t;Retry\r\n\t\t\t86400\t\t;Expire\r\n\t\t\t86400\t\t;Minimum\r\n\t\t)\r\n@\t86400\tIN\tNS\tpdns1.ultradns.net.\r\n@\t86400\tIN\tNS\tpdns2.ultradns.net.\r\n@\t86400\tIN\tNS\tpdns3.ultradns.org.\r\n@\t86400\tIN\tNS\tpdns4.ultradns.org.\r\n@\t86400\tIN\tNS\tpdns5.ultradns.info.\r\n@\t86400\tIN\tNS\tpdns6.ultradns.co.uk.\r\nwww\t300\tIN\tA\t204.74.99.100\r\n" + } + ] + } + ], + "description": "This folder contains endpoints for monitoring asynchronous background tasks (e.g., zone snapshots or exports):\n\n- When you invoke an operation that returns **202 Accepted**, the response headers include an `x-task-id`.\n \n- The collection’s pre‑request scripts save that ID to the `{{currentTask}}` variable.\n \n- Use these endpoints to:\n \n - **Check status** of the task referenced by `{{currentTask}}`\n \n - **Retrieve results** once the task completes\n \n- Running any new task‑generating request will overwrite `{{currentTask}}`, so poll status before kicking off another job." + }, + { + "name": "Reports", + "item": [ + { + "name": "Create NXDomain Report", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "if (utils.isNotSet(pm.environment.get(\"reports_startDate\")) && utils.isNotSet(pm.environment.get(\"reports_endDate\"))) {", + " // If either value isn't set then use a default of the last 30 days", + " const reportDates = utils.lastXDays(30);", + "", + " pm.environment.set(\"reports_startDate\", reportDates[\"start\"]);", + " pm.environment.set(\"reports_endDate\", reportDates[\"end\"]);", + "}", + "", + "const requiredVariables = [\"zones_zoneName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"hostQueryVolume\": {\n \"startDate\": \"{{reports_startDate}}\",\n \"endDate\": \"{{reports_endDate}}\",\n \"zoneNames\": [\n \"{{zones_zoneName}}\"\n ]\n },\n \"sortFields\": {\n \"nxdomainCount\": \"DESC\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v1/reports/dns_resolution/query_volume/host?advance=true&reportType=ADVANCED_NXDOMAINS&limit=100000", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "reports", + "dns_resolution", + "query_volume", + "host" + ], + "query": [ + { + "key": "advance", + "value": "true" + }, + { + "key": "reportType", + "value": "ADVANCED_NXDOMAINS" + }, + { + "key": "limit", + "value": "100000" + } + ] + }, + "description": "Retrieves an advanced NXDOMAIN report, breaking down “no-such-domain” responses by host over a specified date range. This call is asynchronous and returns a JSON payload containing a `requestId` (saved automatically to `reports_requestId`). If you don’t set `reports_startDate` or `reports_endDate`, a pre-request script defaults them to the last 30 days.\n\n**Required variables**\n\n- `reports_startDate` – report start date (YYYY-MM-DD)\n \n- `reports_endDate` – report end date (YYYY-MM-DD)\n \n- `zones_zoneName` – DNS zone to include in the report\n \n\n**Query parameters**\n\n- `advance=true` – enable advanced reporting mode\n \n- `reportType=ADVANCED_NXDOMAINS` – select the NXDOMAIN breakdown report\n \n- `limit` (optional) – maximum number of host entries to return\n \n\n**Request body**\n\n- `hostQueryVolume`: object with `startDate`, `endDate`, and a `zoneNames` array\n \n- `sortFields`: maps field names (e.g., `nxdomainCount`) to `\"ASC\"` (ascending) or `\"DESC\"` (descending) to control result order\n \n\nOnce invoked, note that the response’s `requestId` is stored in `reports_requestId`. Use that ID with the Reports “Retrieve Report” endpoint to poll for status and retrieve the completed data." + }, + "response": [ + { + "name": "Create NXDomain Report", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"hostQueryVolume\": {\n \"startDate\": \"{{reports_startDate}}\",\n \"endDate\": \"{{reports_endDate}}\",\n \"zoneNames\": [\n \"{{zones_zoneName}}\"\n ]\n },\n \"sortFields\": {\n \"nxdomainCount\": \"DESC\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/v1/reports/dns_resolution/query_volume/host?advance=true&reportType=ADVANCED_NXDOMAINS&limit=100000", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "reports", + "dns_resolution", + "query_volume", + "host" + ], + "query": [ + { + "key": "advance", + "value": "true" + }, + { + "key": "reportType", + "value": "ADVANCED_NXDOMAINS" + }, + { + "key": "limit", + "value": "100000" + } + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:48:01 GMT" + }, + { + "key": "Location", + "value": "https://api.ultradns.com/v1/requests/HQV_NXD-f8a26553-33f3-4305-af81-ecbedd010a96" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "60" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"requestId\": \"HQV_NXD-f8a26553-33f3-4305-af81-ecbedd010a96\"\n}" + } + ] + }, + { + "name": "Zero Query Report", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "if (utils.isNotSet(pm.environment.get(\"reports_startDate\")) && utils.isNotSet(pm.environment.get(\"reports_endDate\"))) {", + " // If either value isn't set then use a default of the last 30 days", + " const reportDates = utils.lastXDays(30);", + "", + " pm.environment.set(\"reports_startDate\", reportDates[\"start\"]);", + " pm.environment.set(\"reports_endDate\", reportDates[\"end\"]);", + "}", + "", + "const requiredVariables = [\"subaccounts_accountName\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"zeroZoneQueryVolume\": {\r\n \"accountName\": \"{{subaccounts_accountName}}\",\r\n \"reportStartDate\": \"{{reports_startDate}}\",\r\n \"reportEndDate\": \"{{reports_endDate}}\",\r\n \"wrap\": true\r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/reports/dns_resolution/query_volume/zone/no_queries", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "reports", + "dns_resolution", + "query_volume", + "zone", + "no_queries" + ] + }, + "description": "Retrieves a Zero‑Query report listing all zones under a specified account that received no DNS queries in the given date range. This call is asynchronous and returns a JSON payload containing a `requestId`, which is saved to `reports_requestId` by the collection. If you omit `reports_startDate` or `reports_endDate`, they default to the last 30 days.\n\n**Required variables**\n\n- `accountName` – the account to report on (e.g., use `subaccounts_accountName` or any accessible account)\n \n- `reports_startDate` – report start date (YYYY-MM-DD)\n \n- `reports_endDate` – report end date (YYYY-MM-DD)\n \n- `wrap` – boolean (true to wrap results in an envelope)\n \n\nOnce invoked, pass the returned `requestId` to the Reports “Retrieve Report” endpoint to poll for completion and retrieve the final data." + }, + "response": [ + { + "name": "Zero Query Report", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"zeroZoneQueryVolume\": {\r\n \"accountName\": \"{{subaccounts_accountName}}\",\r\n \"reportStartDate\": \"{{reports_startDate}}\",\r\n \"reportEndDate\": \"{{reports_endDate}}\",\r\n \"wrap\": true\r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/reports/dns_resolution/query_volume/zone/no_queries", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "reports", + "dns_resolution", + "query_volume", + "zone", + "no_queries" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:59:01 GMT" + }, + { + "key": "Location", + "value": "https://api.ultradns.com/requests/ZQZV_WRAP-e8f4485d-060c-446e-8fe1-f3a83cf52b33" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "62" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"requestId\": \"ZQZV_WRAP-e8f4485d-060c-446e-8fe1-f3a83cf52b33\"\n}" + } + ] + }, + { + "name": "Retrieve Report", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"reports_requestId\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v1/requests/{{reports_requestId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "requests", + "{{reports_requestId}}" + ] + }, + "description": "Retrieves the results of a previously generated report. Requires the `reports_requestId` variable, which the collection automatically populates from the report creation response. Returns the report data payload once complete, or status and error details if still processing or failed." + }, + "response": [ + { + "name": "Retrieve Report", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/v1/requests/{{reports_requestId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "requests", + "{{reports_requestId}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Tue, 17 Jun 2025 23:59:17 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "23" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "Zone Name,Account Name\n" + } + ] + } + ], + "description": "This folder contains all endpoints for generating and fetching DNS analytics reports:\n\n- **Create a report**\n \n - `POST /reports` (or similar)\n \n - Response body includes a JSON `id` for your report\n \n - That `id` is saved automatically to `{{currentReport}}`\n \n- **Check report status & retrieve results**\n \n - `GET /reports/requests/{{currentReport}}`\n \n - Returns the current state (pending, complete, failed) and, once ready, the report data\n \n- **Notes**\n \n - The report ID lives in the `{{currentReport}}` variable by default\n \n - Running any new “create report” request will overwrite `{{currentReport}}`—poll or store it elsewhere if you need multiple reports in flight simultaneously" + }, + { + "name": "Webhook", + "item": [ + { + "name": "Test Endpoint", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"username\", \"webhook_endpointUrl\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "// Parse the response body", + "let resp = pm.response.json();", + "", + "// Check if \"telemetryEventId\" exists in the response", + "if (resp.hasOwnProperty(\"telemetryEventId\")) {", + " // Set the \"webhook_telemetryId\" collection variable", + " pm.environment.set(\"webhook_telemetryId\", resp.telemetryEventId);", + " console.log(`Telemetry ID saved: ${resp.telemetryEventId}`);", + "} else {", + " console.error(\"Error: 'telemetryEventId' not found in the response body.\");", + "}" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"url\": \"{{webhook_endpointUrl}}\",\r\n \"type\": \"TEST_TELEMETRY_WEBHOOK\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/telemetryWebhook/test", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "telemetryWebhook", + "test" + ] + }, + "description": "Creates a test telemetry event against your configured webhook to verify connectivity.\n\n**Required variables**\n\n- `username` – the UltraDNS account name (may differ from your login username)\n \n- `webhook_endpointUrl` – the URL to receive the test event\n \n\nA post‑request script automatically extracts `telemetryEventId` from the JSON response and saves it to the `webhook_telemetryId` environment variable. Use that value with the Verify endpoint to confirm delivery." + }, + "response": [ + { + "name": "Test Endpoint", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"url\": \"{{webhook_endpointUrl}}\",\r\n \"type\": \"TEST_TELEMETRY_WEBHOOK\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/telemetryWebhook/test", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "telemetryWebhook", + "test" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:00:12 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"telemetryEventId\": \"a7dc9223-cdff-4435-acfd-0f8df342f844\",\n \"telemetryEventType\": \"TEST_TELEMETRY_WEBHOOK\",\n \"telemetryEventTime\": \"2025-06-18 12:00:13.224\",\n \"environment\": \"\",\n \"accountName\": \"postman-example\"\n}" + } + ] + }, + { + "name": "Verify", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"username\", \"webhook_telemetryId\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/telemetryWebhook/test/{{webhook_telemetryId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "telemetryWebhook", + "test", + "{{webhook_telemetryId}}" + ] + }, + "description": "Verifies delivery of a test telemetry event to your webhook. Requires the `username` (account name) and `webhook_telemetryId` (saved by the Test endpoint’s script). Returns a JSON payload indicating success or error details." + }, + "response": [ + { + "name": "Verify", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/telemetryWebhook/test/{{webhook_telemetryId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "telemetryWebhook", + "test", + "{{webhook_telemetryId}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:00:29 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "20" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"status\": \"Unknown\"\n}" + } + ] + }, + { + "name": "Create", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const requiredVariables = [\"username\", \"webhook_endpointUrl\"]; ", + "utils.checkVars(requiredVariables, true);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"webhooks\": [\r\n {\r\n \"enable\": true,\r\n \"url\": \"{{webhook_endpointUrl}}\",\r\n \"include\": {\r\n \"ALL_CHANGES\": true\r\n }\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/PUSH_NOTIFICATIONS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "PUSH_NOTIFICATIONS" + ] + }, + "description": "Creates a push‑notification webhook configuration that delivers telemetry events for all account changes.\n\n**Requires:**\n\n- `username` – the UltraDNS account name\n \n- `webhook_endpointUrl` – the URL to receive live notifications\n \n\nBy default, this enables notifications for `ALL_CHANGES`. On success, returns the created webhook configuration in the response payload." + }, + "response": [ + { + "name": "Create", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"webhooks\": [\r\n {\r\n \"enable\": true,\r\n \"url\": \"{{webhook_endpointUrl}}\",\r\n \"include\": {\r\n \"ALL_CHANGES\": true\r\n }\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/PUSH_NOTIFICATIONS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "PUSH_NOTIFICATIONS" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:00:47 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "24" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + } + ], + "description": "This folder contains all endpoints for managing UDNS push‑notification webhooks:\n\n- **Create Webhook** \n \n Sends your `url`, `headers`, and event filters to UDNS. (No prior validation required, but you’ll typically want to test first.)\n \n- **Test Webhook** \n \n Triggers a sample telemetry event to your configured endpoint.\n \n - On success, the response body returns an `eventId`\n \n - That `eventId` is saved to `{{currentWebhookEventId}}`\n \n- **Verify Webhook Event** \n \n Polls `/webhooks/events/{{currentWebhookEventId}}` to confirm delivery status and any response details.\n \n\n**Notes:**\n\n- Replace or set `webhookUrl` and any auth headers in your environment before calling **Create Webhook**.\n \n- Running **Test Webhook** will overwrite `{{currentWebhookEventId}}`. Poll or store it elsewhere if you need to verify multiple events." + }, + { + "name": "DNSSEC Multi-Signer", + "item": [ + { + "name": "Initialize DNSSEC Settings", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"dnssecSettings\": {\r\n \"dnskeyTtl\": {{dnssec_dnskey_ttl}},\r\n \"rrsigValidity\": {{dnssec_rrsig_validity}} \r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "DNSSEC_SETTINGS" + ] + }, + "description": "UltraDNS allows the configuration of some default values to be used when signing a zone. These \nconfigurations are then set for DNSSEC signing of every zone in the account:\n\n- DNSKEY TTL - The Time to Live (TTL) in seconds, used for the DNSKEY resource record set. Default value is 86400 (1 day) with valid values in the range of 300-172800 seconds (5 minutes - 2 days).\n \n- RRSIG Validity Period - Sets the RRSIG validity interval, in days when signing responses. Default value of 14 (2 weeks), with valid values in the range of 5-30 (days).\n \n\nThese default value preferences can be set using the API as shown below. Once set, these values will be used for every zone signing, rollover, and resigning action on every zone in the account.\n\nNOTE: If you have previously set these values with a call to this API then you will need to use the Update (PUT) API call to update them and the Remove (DELETE) API call to delete them." + }, + "response": [ + { + "name": "Initialize DNSSEC Settings", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"dnssecSettings\": {\r\n \"dnskeyTtl\": {{dnssec_dnskey_ttl}},\r\n \"rrsigValidity\": {{dnssec_rrsig_validity}} \r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "DNSSEC_SETTINGS" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:01:57 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "24" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "Update DNSSEC Settings Copy", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"dnssecSettings\": {\r\n \"dnskeyTtl\": {{dnssec_dnskey_ttl}},\r\n \"rrsigValidity\": {{dnssec_rrsig_validity}} \r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "DNSSEC_SETTINGS" + ] + }, + "description": "UltraDNS allows the configuration of some default values to be used when signing a zone. These \nconfigurations are then set for DNSSEC signing of every zone in the account:\n\n- DNSKEY TTL - The Time to Live (TTL) in seconds, used for the DNSKEY resource record set. Default value is 86400 (1 day) with valid values in the range of 300-172800 seconds (5 minutes - 2 days).\n \n- RRSIG Validity Period - Sets the RRSIG validity interval, in days when signing responses. Default value of 14 (2 weeks), with valid values in the range of 5-30 (days).\n \n\nThese default value preferences can be set using the API as shown below. Once set, these values will be used for every zone signing, rollover, and resigning action on every zone in the account.\n\nNOTE: Use the Initialize (POST) API call to initially set these values and the Remove (DELETE) API call to delete them." + }, + "response": [ + { + "name": "Update DNSSEC Settings Copy", + "originalRequest": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"dnssecSettings\": {\r\n \"dnskeyTtl\": {{dnssec_dnskey_ttl}},\r\n \"rrsigValidity\": {{dnssec_rrsig_validity}} \r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "DNSSEC_SETTINGS" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:02:15 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "24" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "Remove DNSSEC Settings", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "DNSSEC_SETTINGS" + ] + }, + "description": "UltraDNS allows the configuration of some default values to be used when signing a zone. These \nconfigurations are then set for DNSSEC signing of every zone in the account:\n\n- DNSKEY TTL - The Time to Live (TTL) in seconds, used for the DNSKEY resource record set. Default value is 86400 (1 day) with valid values in the range of 300-172800 seconds (5 minutes - 2 days).\n \n- RRSIG Validity Period - Sets the RRSIG validity interval, in days when signing responses. Default value of 14 (2 weeks), with valid values in the range of 5-30 (days).\n \n\nThese default value preferences can be set using the API as shown below. Once set, these values will be used for every zone signing, rollover, and resigning action on every zone in the account.\n\nNOTE: Use the Initialize (POST) API call to initially set these values and the Update (PUT) API call to update them." + }, + "response": [ + { + "name": "Remove DNSSEC Settings", + "originalRequest": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/accounts/{{username}}/settings/DNSSEC_SETTINGS", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "accounts", + "{{username}}", + "settings", + "DNSSEC_SETTINGS" + ] + } + }, + "status": "No Content", + "code": 204, + "_postman_previewlanguage": "plain", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:16:35 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": null + } + ] + }, + { + "name": "DNSSEC Sign Zone", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + }, + "description": "This API is used to DNSSEC sign a zone on UltraDNS and can be used on both primary and secondary zones.\n\nIf you have external signer DNSKEY information you can include that as an _externalKeys_ element in the JSON payload (see [Update External Signer](https://go.postman.co/workspace/My-Workspace~44d8667f-697e-43dd-8c23-aea1d7afb89c/documentation/269716-96acc28c-c730-4484-9a15-43f2bb753d3a?entity=request-09c10a66-1e56-4e2f-8504-9f15c8dd7766)), otherwise the payload is empty." + }, + "response": [ + { + "name": "DNSSEC Sign Zone", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:02:33 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "DNSSEC Un-Sign Zone", + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + }, + "description": "This API call will unsign a DNSSEC signed zone, removing all DNSKEY information (including external keys)." + }, + "response": [ + { + "name": "DNSSEC Un-Sign Zone", + "originalRequest": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + } + }, + "status": "No Content", + "code": 204, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:16:26 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": null + } + ] + }, + { + "name": "Get DS Records", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + }, + "description": "Provides detailed information regarding the current DNSSEC status of a zone. This API call can be used to get the DS (Designated Signer) records for the zone that can be used by the parent zone to establish a chain-of-trust for the zone." + }, + "response": [ + { + "name": "Get DS Records", + "originalRequest": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:02:47 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "Close" + } + ], + "cookie": [], + "body": "{\n \"status\": \"SIGNED\",\n \"policy\": {\n \"algorithm\": \"ECDSAP256SHA256\",\n \"securityType\": \"NSEC_ON_THE_FLY\",\n \"rrsigSignatureDuration\": 30,\n \"dnskeyTtl\": 172800,\n \"keyPolicy\": [\n {\n \"type\": \"ZSK\",\n \"bitLength\": 256,\n \"keyRolloverFrequency\": 30\n },\n {\n \"type\": \"KSK\",\n \"bitLength\": 256,\n \"keyRolloverFrequency\": 365\n }\n ]\n },\n \"keys\": [\n {\n \"type\": \"ZSK\",\n \"bitLength\": 256,\n \"keyRolloverFrequency\": 30,\n \"status\": \"CURRENT\",\n \"created\": \"2025-06-18T00:02:34Z\",\n \"nextRoll\": \"2025-07-18T00:02:34Z\",\n \"keyId\": 53083,\n \"publicKey\": \"q5wE5b6RtDeR0vY553t+V6k3+T1jZ5UDiDfXhtKgkbrBQJvUd0yklPkTGqKzehg8OJRxLdCttM0uYn4PreB5Ng==\",\n \"dnsKeyRecord\": \"domain.com. 172800 IN DNSKEY 256 3 13 q5wE5b6RtDeR0vY553t+V6k3+T1jZ5UDiDfXhtKgkbrBQJvUd0yklPkTGqKzehg8OJRxLdCttM0uYn4PreB5Ng==\"\n },\n {\n \"type\": \"KSK\",\n \"bitLength\": 256,\n \"keyRolloverFrequency\": 365,\n \"status\": \"CURRENT\",\n \"created\": \"2025-06-18T00:02:34Z\",\n \"nextRoll\": \"2026-06-18T00:02:34Z\",\n \"keyId\": 17461,\n \"publicKey\": \"zcF4e9AjcvGpBD3q4wvObit/Zg7P2+PGkXDoCrECz5n6kgVxoptvxIQHaFC39lEo8Q1mQM3t6uMna/v0/SSmog==\",\n \"dsRecords\": [\n \"17461 13 1 63F11070CADCF0E36AA32561192A62C7F129531A\",\n \"17461 13 2 56F7230A6F4B4C2113AB46F134C5FDDDAF551FAD82DD2607ECDCF9BF7C94AF33\"\n ],\n \"dnsKeyRecord\": \"domain.com. 172800 IN DNSKEY 257 3 13 zcF4e9AjcvGpBD3q4wvObit/Zg7P2+PGkXDoCrECz5n6kgVxoptvxIQHaFC39lEo8Q1mQM3t6uMna/v0/SSmog==\"\n }\n ],\n \"lastModifiedDateTime\": \"2025-06-18T00:02:34Z\",\n \"lastModifiedZoneDateTime\": \"2025-06-18T00:02:34Z\",\n \"resignNeeded\": false\n}" + } + ] + }, + { + "name": "Update External Signer", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"externalKeys\":[\r\n {\r\n \"ksk\":[\"{{dnssec_extkey_ksk}}\"],\r\n \"zsk\":[\"{{dnssec_extkey_zsk}}\"]\r\n }\r\n ]\r\n} ", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + }, + "description": "Configure external signer keys (KSK and ZSK) for a DNSSEC signed zone. KSK and ZSK DNSKEY records are formatted as follows:\n\n```\n \n\n ```\n\nNOTE: For an unsigned zone you can change the method to POST and set the value of _externalKeys_ to both DNSSEC sign a zone and install the DNSKEY records from an external provider." + }, + "response": [ + { + "name": "Update External Signer", + "originalRequest": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"externalKeys\":[\r\n {\r\n \"ksk\":[\"{{dnssec_extkey_ksk}}\"],\r\n \"zsk\":[\"{{dnssec_extkey_zsk}}\"]\r\n }\r\n ]\r\n} ", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:15:49 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "Remove External Signer", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"externalKeys\":[]\r\n} ", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + }, + "description": "Remove DNSKEY records for external signer from a DNSSEC signed zone.\n\nNOTE: External keys will not show up in the UltraDNS portal. Run a _dig_ command against the zone for DNSKEY records to verify the external keys were added. For example:\n\n_\\>> dig @udns1.ultradns.com example.com DNSKEY_" + }, + "response": [ + { + "name": "Remove External Signer", + "originalRequest": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"externalKeys\":[]\r\n} ", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/dnssec", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "dnssec" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:16:11 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "42" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + } + ], + "description": "UltraDNS API endpoints that support [multi-signer DNSSEC](https://ultra-portalstatic.ultradns.com/static/console/docs/DNSSEC-Multi_Signer-Guide.pdf).\n\nUltraDNS DNSSEC uses _online_ (also known as _on-the-fly_) signing in generating signed responses to queries. UltraDNS supports DNSSEC algorithm 13 only for this process. Implementers of multi-signer can add DNSKEY details for external signers using other algorithms as needed, but all UltraDNS generated key information uses algorithm 13 (ECDSA).\n\nAdditionally, UltraDNS signers generate a unique KSK and ZSK for every zone. This approach gives flexibility for zone owners to roll their KSK without impacting other zones that share the KSK information and allows the ZSK to be automatically rolled at regular intervals. The implementation of multi-signer follows the methods described in [RFC 8901 model 2](https://www.rfc-editor.org/rfc/rfc8901.html#name-model-2-unique-ksk-set-and-) where each signer maintains its own unique KSK and ZSK.\n\nSupport of DNSSEC Multi-Signer is derived from, and supports portions of the following RFCs:\n\n- [RFC 8901](https://www.rfc-editor.org/rfc/rfc8901.html) - Multi-Signer DNSSEC Models.\n \n- [RFC 7344](https://www.rfc-editor.org/rfc/rfc7344) - Automating DNSSEC Delegation Trust Maintenance.\n \n- [RFC 8078](https://www.rfc-editor.org/rfc/rfc8078) - Managing DS Records from the Parent via CDS/CDNSKEY.\n \n- [RFC 6781](https://www.rfc-editor.org/rfc/rfc6781.html) - DNSSEC Operational Practices, Version 2." + }, + { + "name": "Traffic Management", + "item": [ + { + "name": "SiteBacker", + "item": [ + { + "name": "Record Priority Update", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Content-Type", + "value": "application/json-patch+json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "[\r\n // JSON DTO (pool record with lowest value for priority field.\r\n {\r\n \"op\": \"replace\",\r\n \"path\": \"/profile/rdataInfo/0/priority\",\r\n \"value\": \"101\"\r\n },\r\n // JSON DTO (pool record with the next highest value for priority field.\r\n {\r\n \"op\": \"replace\",\r\n \"path\": \"/profile/rdataInfo/1/priority\",\r\n \"value\": \"1\"\r\n }\r\n]", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/rrsets/{{sb_rrType}}/{{sb_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "rrsets", + "{{sb_rrType}}", + "{{sb_ownerName}}" + ] + }, + "description": "**Overview** \n \nUpdates the failover/load‑order priority of a single member in a SiteBacker pool. The member is selected by its index in the pool’s member list (the “path” parameter):\n\n- **Index 0** targets the first (lowest‑priority) record\n \n- **Index 1** targets the second record\n \n- And so on for larger pools\n \n\nChanging the member’s `priority` value determines its position in the failover or load‑balancing sequence.\n\n**Usage Notes**\n\n- In a simple two‑member pool (e.g. priorities 1 and 101), you can swap their roles by PATCHing each index without altering the request body.\n \n- For pools with more than two members, adjust each member’s `priority` to reflect the exact ordering you need." + }, + "response": [ + { + "name": "Record Priority Update", + "originalRequest": { + "method": "PATCH", + "header": [ + { + "key": "Content-Type", + "value": "application/json-patch+json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "[\r\n // JSON DTO (pool record with lowest value for priority field.\r\n {\r\n \"op\": \"replace\",\r\n \"path\": \"/profile/rdataInfo/0/priority\",\r\n \"value\": \"101\"\r\n },\r\n // JSON DTO (pool record with the next highest value for priority field.\r\n {\r\n \"op\": \"replace\",\r\n \"path\": \"/profile/rdataInfo/1/priority\",\r\n \"value\": \"1\"\r\n }\r\n]", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/rrsets/{{sb_rrType}}/{{sb_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "rrsets", + "{{sb_rrType}}", + "{{sb_ownerName}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:32:55 GMT" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "Content-Length", + "value": "42" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + }, + { + "name": "Create SiteBacker Pool", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"ttl\": 300,\r\n \"rdata\": [\r\n \"1.1.1.1\",\r\n \"2.2.2.2\",\r\n \"3.3.3.3\",\r\n \"4.4.4.4\"\r\n ],\r\n \"profile\": {\r\n \"@context\": \"http://schemas.ultradns.com/SBPool.jsonschema\",\r\n \"description\": \"Test SiteBacker Pool\",\r\n \"runProbes\": true,\r\n \"actOnProbes\": true,\r\n \"order\": \"FIXED\",\r\n \"maxActive\": 1,\r\n \"failureThreshold\": 0,\r\n \"maxServed\": 1,\r\n \"rdataInfo\": [{\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }],\r\n \"backupRecords\": [{\r\n \"rdata\": \"9.9.9.9\",\r\n \"failoverDelay\":0\r\n }]\r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/rrsets/{{sb_rrType}}/{{sb_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "rrsets", + "{{sb_rrType}}", + "{{sb_ownerName}}" + ] + }, + "description": "**Overview** \n \nCreates a new SiteBacker pool under the specified zone and record owner. The request body must include:\n\n- **rdata**: an array of IP addresses to include in the pool\n \n- **rdataInfo**: one object per IP with:\n \n - `state` (NORMAL, FORCE_ACTIVE, FORCE_FAIL)\n \n - `runProbes` (true / false)\n \n - `priority` (positive integer)\n \n - `failoverDelay` (0 or positive integer)\n \n - `threshold` (positive integer)\n \n - `availableToServe` (true / false)\n \n- **backupRecords**: an array of fallback records, each with:\n \n - `rdata` (IP address)\n \n - `failoverDelay` (0 or positive integer)" + }, + "response": [ + { + "name": "Create SiteBacker Pool", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"ttl\": 300,\r\n \"rdata\": [\r\n \"1.1.1.1\",\r\n \"2.2.2.2\",\r\n \"3.3.3.3\",\r\n \"4.4.4.4\"\r\n ],\r\n \"profile\": {\r\n \"@context\": \"http://schemas.ultradns.com/SBPool.jsonschema\",\r\n \"description\": \"Test SiteBacker Pool\",\r\n \"runProbes\": true,\r\n \"actOnProbes\": true,\r\n \"order\": \"FIXED\",\r\n \"maxActive\": 1,\r\n \"failureThreshold\": 0,\r\n \"maxServed\": 1,\r\n \"rdataInfo\": [{\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }, {\r\n \"state\": \"NORMAL\",\r\n \"runProbes\": true,\r\n \"priority\": 1,\r\n \"failoverDelay\": 0,\r\n \"threshold\": 1,\r\n \"availableToServe\": true\r\n }],\r\n \"backupRecords\": [{\r\n \"rdata\": \"9.9.9.9\",\r\n \"failoverDelay\":0\r\n }]\r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/zones/{{zones_zoneName}}/rrsets/{{sb_rrType}}/{{sb_ownerName}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "zones", + "{{zones_zoneName}}", + "rrsets", + "{{sb_rrType}}", + "{{sb_ownerName}}" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Headers", + "value": "Origin, X-Requested-With, Content-Type, Accept, Authorization, UltraClient" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, GET, OPTIONS, DELETE, PUT, PATCH" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Max-Age", + "value": "3600" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Security-Policy", + "value": "default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 18 Jun 2025 00:32:33 GMT" + }, + { + "key": "Location", + "value": "http://api.ultradns.com/zones/domain.com/rrsets/A/sitebacker" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubDomains; preload" + }, + { + "key": "Vary", + "value": "Origin" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Method" + }, + { + "key": "Vary", + "value": "Access-Control-Request-Headers" + }, + { + "key": "Vary", + "value": "Accept-Encoding, User-Agent" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Download-Options", + "value": "noopen" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + }, + { + "key": "X-Permitted-Cross-Domain-Policies", + "value": "none" + }, + { + "key": "X-Xss-Protection", + "value": "1 ; mode=block" + }, + { + "key": "transfer-encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Successful\"\n}" + } + ] + } + ], + "description": "This folder contains endpoints for managing SiteBacker pools—a traffic‑management feature that groups multiple IPs under one DNS record and uses health‑check probes to steer queries based on endpoint health and defined priorities.\n\n- **Create Pool**: provision a new pool of endpoints for a given zone/record, complete with probe settings and failover rules\n \n- **Update Member Priority**: reorder pool members to control failover order" + } + ], + "description": "This folder groups UltraDNS’s advanced traffic‑management features, each in its own subfolder:\n\n- **SiteBacker**: configure health‑check probes that monitor endpoints and automatically steer traffic away from failures\n \n- **Direction**: set up geography‑aware routing so queries resolve to the closest or best‑suited data center\n \n- **Traffic Controller**: create load‑balancing rules to distribute DNS traffic across multiple targets based on weight, priority, or custom logic\n \n- **\\[Other advanced services\\]**: each subfolder covers a specific traffic‑management API for steering, failover, and performance optimization\n \n\nUse these endpoints to build resilient, geo‑intelligent DNS strategies that adapt in real time to health, location, and load." + } + ], + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{accessToken}}", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "if (!pm.environment.name) {", + " throw new Error(\"MissingEnvironment: No environment selected. Please select an environment before running the request.\");", + "}", + "", + "utils = {", + " isNotSet: function(val) {", + " const empty = [null, undefined, \"\", \"null\", \"undefined\"];", + " const placeholders = [\"HASH\", \"PASSWORD\", \"UNIX_TIMESTAMP\", \"GUID\"];", + " return empty.includes(val) || placeholders.includes(val);", + " },", + " checkVars: function(values, checkEnv=false) {", + " values.forEach((varName) => {", + " let value, errorType;", + " if (checkEnv) {", + " value = pm.environment.get(varName);", + " errorType = \"MissingEnvironmentVariable\";", + " } else {", + " value = pm.collectionVariables.get(varName);", + " errorType = \"MissingCollectionVariable\";", + " }", + " if (utils.isNotSet(value)) {", + " throw new Error(`${errorType}: The variable \"${varName}\" is not set or is null. Please set a valid value before proceeding.`);", + " }", + " });", + " },", + " lastXDays: function(days) {", + " if (days > 30) {", + " throw new Error(`You specified ${days.toString()} days but the max is 30.`);", + " }", + " const yesterday = new Date();", + " yesterday.setDate(yesterday.getDate() - 1);", + " const startDate = new Date();", + " startDate.setDate(yesterday.getDate() - days);", + " return {", + " \"start\": startDate.toISOString().split('T')[0],", + " \"end\": yesterday.toISOString().split('T')[0]", + " }", + " }", + "};", + "", + "utils.checkVars([\"username\", \"password\"], true);", + "", + "const username = pm.environment.get(\"username\");", + "const password = pm.environment.get(\"password\");", + "", + "utils.checkVars([\"baseUrl\"]);", + "const baseUrl = pm.collectionVariables.get('baseUrl');", + "", + "const currentAccessToken = pm.environment.get('accessToken');", + "const currentRefreshToken = pm.environment.get('refreshToken');", + "const tokenTimestamp = pm.environment.get('tokenTimestamp');", + "", + "function setTokens(accessToken, refreshToken) {", + " const now = Date.now();", + " pm.environment.set('accessToken', accessToken);", + " pm.environment.set('refreshToken', refreshToken);", + " pm.environment.set('tokenTimestamp', now.toString());", + "}", + "", + "function getNewTokens(un, pw) {", + " const payload = {", + " grant_type: 'password',", + " username: un,", + " password: pw", + " };", + "", + " pm.sendRequest({", + " url: `${baseUrl}/authorization/token`,", + " method: 'POST',", + " header: 'Content-Type:application/x-www-form-urlencoded',", + " body: {", + " mode: 'urlencoded',", + " urlencoded: Object.keys(payload).map(key => ({key, value: payload[key]}))", + " }", + " }, (err, res) => {", + " if (err) {", + " console.error(`AuthFailed: ${err}`);", + " } else {", + " setTokens(res.json().accessToken, res.json().refreshToken);", + " }", + " });", + "}", + "", + "if (utils.isNotSet(currentAccessToken) || utils.isNotSet(tokenTimestamp)) {", + " getNewTokens(username, password);", + "} else {", + " const fiftyFiveMinutes = 55 * 60 * 1000; // milliseconds", + " const now = Date.now();", + " const timePassed = now - parseInt(tokenTimestamp, 10);", + "", + " // If more than 55min has passed, we try to refresh the token", + " if (timePassed > fiftyFiveMinutes) {", + " if (currentRefreshToken) {", + " const payload = {", + " grant_type: 'refresh_token',", + " refresh_token: currentRefreshToken", + " };", + "", + " pm.sendRequest({", + " url: `${baseUrl}/authorization/token`,", + " method: 'POST',", + " header: 'Content-Type:application/x-www-form-urlencoded',", + " body: {", + " mode: 'urlencoded',", + " urlencoded: Object.keys(payload).map(key => ({key, value: payload[key]}))", + " }", + " }, (err, res) => {", + " if (err || res.code !== 200) {", + " // If there's an error or the refresh token is stale", + " console.log(`RefreshFailed: Bad refresh token, re-authenticating: ${err}`)", + " getNewTokens(username, password);", + " } else {", + " setTokens(res.json().accessToken, res.json().refreshToken);", + " }", + " });", + " } else {", + " getNewTokens(username, password);", + " }", + " }", + "}" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Check if the x-task-id header is present in the response", + "let taskId = pm.response.headers.get(\"x-task-id\");", + "", + "if (taskId) {", + " pm.environment.set(\"currentTask\", taskId);", + " console.log(`Saved x-task-id: ${taskId} to currentTask collection variable.`);", + "}", + "", + "// Check if there's a response body and if the response can be parsed as JSON", + "if (pm.response.text() && pm.response.headers.get('Content-Type').includes('application/json')) {", + " try {", + " let resp = pm.response.json();", + " ", + " // Check if \"requestId\" exists in the response", + " if (resp.hasOwnProperty(\"requestId\")) {", + " // Set the \"requestId\" collection variable", + " pm.environment.set(\"reports_requestId\", resp.requestId);", + " console.log(`Request ID saved: ${resp.requestId}`);", + " }", + " } catch (e) {", + " // This will catch any errors in parsing the JSON, but do nothing", + " // Just in case, so it doesn't somehow cause non-JSON responses to error", + " }", + "}", + "" + ] + } + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "https://api.ultradns.com", + "type": "string" + } + ] } \ No newline at end of file