{
  "openapi": "3.0.1",
  "info": {
    "title": "DNS Cutover Convergence Gate with Webhook Receipt",
    "description": "Polls public DNS-over-HTTPS resolvers until a record matches the expected value at every resolver, then sends one webhook and writes one sealed receipt. Built for the moment of a cutover, so the next step can start. HTTP only, no browser, no proxy, no dat",
    "version": "0.2",
    "x-build-id": "VPL7a5N9mHatrgpAC"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/kingii98~dns-cutover-convergence-gate-with-webhook-receipt/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-kingii98-dns-cutover-convergence-gate-with-webhook-receipt",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/kingii98~dns-cutover-convergence-gate-with-webhook-receipt/runs": {
      "post": {
        "operationId": "runs-sync-kingii98-dns-cutover-convergence-gate-with-webhook-receipt",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/kingii98~dns-cutover-convergence-gate-with-webhook-receipt/run-sync": {
      "post": {
        "operationId": "run-sync-kingii98-dns-cutover-convergence-gate-with-webhook-receipt",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "checks",
          "resolvers",
          "pollIntervalSeconds",
          "maxWaitMinutes",
          "timeoutSeconds"
        ],
        "properties": {
          "checks": {
            "title": "Records to watch",
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "description": "1 to 20 items. Each item holds domain (the fully qualified name), record_type (A, AAAA, CNAME, MX, TXT or NS) and expected (the value or the list of values that the record must hold once the cutover is complete). A check converges only when the answer set is exactly the expected set, so a resolver that still serves the old value beside the new one does not count. Write an MX value as \"10 mail.example.com\". Write a TXT value without the surrounding quotes.",
            "default": [
              {
                "domain": "one.one.one.one",
                "record_type": "A",
                "expected": [
                  "1.0.0.1",
                  "1.1.1.1"
                ]
              },
              {
                "domain": "dns.google",
                "record_type": "A",
                "expected": [
                  "8.8.4.4",
                  "8.8.8.8"
                ]
              },
              {
                "domain": "dns.google",
                "record_type": "AAAA",
                "expected": [
                  "2001:4860:4860::8844",
                  "2001:4860:4860::8888"
                ]
              }
            ]
          },
          "resolvers": {
            "title": "Public DNS-over-HTTPS resolvers",
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "description": "1 to 20 HTTPS URLs. Each one must answer an RFC 8484 wire-format GET request. The default set holds 8 public resolvers. A URL that resolves to a loopback, private or reserved address is skipped and the reason is written to the log.",
            "default": [
              "https://cloudflare-dns.com/dns-query",
              "https://dns.google/dns-query",
              "https://dns.quad9.net/dns-query",
              "https://unfiltered.adguard-dns.com/dns-query",
              "https://doh.opendns.com/dns-query",
              "https://dns.mullvad.net/dns-query",
              "https://doh.sb/dns-query",
              "https://dns.nextdns.io/dns-query"
            ],
            "items": {
              "type": "string"
            }
          },
          "pollIntervalSeconds": {
            "title": "Poll interval (seconds)",
            "minimum": 30,
            "maximum": 900,
            "type": "integer",
            "description": "The wait between two poll cycles. The minimum is 30 seconds, so the resolvers are not overloaded.",
            "default": 60
          },
          "maxWaitMinutes": {
            "title": "Maximum wait (minutes)",
            "minimum": 1,
            "maximum": 60,
            "type": "integer",
            "description": "The run stops at this limit and reports a timeout. A timeout is a normal result and the run still succeeds.",
            "default": 30
          },
          "requireAllResolvers": {
            "title": "Require every resolver to agree",
            "type": "boolean",
            "description": "Keep this on for a cutover gate: every resolver in the list must serve the expected value. Switch it off to converge as soon as one resolver agrees.",
            "default": true
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "Optional public HTTPS URL. One JSON POST goes out when a check converges and one goes out when a check reaches the wait limit. Chain your next cutover step onto it. Loopback, private and reserved addresses are refused. Leave it empty to read the result in the dataset only.",
            "default": ""
          },
          "timeoutSeconds": {
            "title": "Request timeout (seconds)",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Timeout for one resolver query and for one webhook POST.",
            "default": 10
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}