swagger: '2.0' info: title: 'AdGuard Home' description: 'AdGuard Home REST API. Admin web interface is built on top of this REST API.' version: 0.92.0 schemes: - http basePath: /control produces: - application/json tags: - name: global description: 'AdGuard Home server general settings and controls' - name: log description: 'AdGuard Home query log' - name: stats description: 'AdGuard Home statistics' - name: i18n description: 'Application localization' - name: filtering description: 'Rule-based filtering' - name: safebrowsing description: 'Blocking malware/phishing sites' - name: parental description: 'Blocking adult and explicit materials' - name: safesearch description: 'Enforce family-friendly results in search engines' - name: dhcp description: 'Built-in DHCP server controls' paths: # API TO-DO LIST # TODO: Use JSON where it is possible # TODO: Use lower_case for all objects' properties # TODO: Move to definitions what's missing from there # -------------------------------------------------- # General settings and controls # -------------------------------------------------- /status: get: tags: - global operationId: status summary: 'Get DNS server current status and general settings' produces: - application/json responses: 200: description: OK schema: $ref: "#/definitions/ServerStatus" /enable_protection: post: tags: - global operationId: enableProtection summary: "Enable protection (turns on dnsfilter module in coredns)" responses: 200: description: OK /disable_protection: post: tags: - global operationId: disableProtection summary: "Disable protection (turns off filtering, sb, parental, safesearch temporarily by disabling dnsfilter module in coredns)" responses: 200: description: OK /set_upstream_dns: post: tags: - global operationId: setUpstreamDNS summary: 'Set upstream DNS for coredns, empty value will reset it to default values' consumes: - text/plain parameters: - in: body name: upstream description: 'Upstream servers, separated by newline or space, port is optional after colon' schema: # TODO: use JSON type: string example: | 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 192.168.1.104:53535 responses: 200: description: OK /test_upstream_dns: post: tags: - global operationId: testUpstreamDNS summary: 'Test upstream DNS' consumes: - text/plain parameters: - in: body name: upstream description: 'Upstream servers, separated by newline or space, port is optional after colon' schema: # TODO: use JSON type: string example: | 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 192.168.1.104:53535 responses: 200: description: 'Status of testing each requested server, with "OK" meaning that server works, any other text means an error.' examples: application/json: 1.1.1.1: OK 1.0.0.1: OK 8.8.8.8: OK 8.8.4.4: OK "192.168.1.104:53535": "Couldn't communicate with DNS server" /version.json: get: tags: - global operationId: getVersionJson summary: 'Gets information about the latest available version of AdGuard' produces: - 'application/json' responses: 200: description: 'Version info' schema: $ref: "#/definitions/VersionInfo" 500: description: 'Cannot write answer' 502: description: 'Cannot retrieve the version.json file contents' # -------------------------------------------------- # Query log methods # -------------------------------------------------- /querylog: get: tags: - log operationId: queryLog summary: 'Get DNS server query log' parameters: - in: query name: download type: boolean description: 'If any value is set, make the browser download the query instead of displaying it by setting Content-Disposition header' responses: 200: description: OK schema: $ref: '#/definitions/QueryLog' /querylog_enable: post: tags: - log operationId: querylogEnable summary: 'Enable querylog' responses: 200: description: OK /querylog_disable: post: tags: - log operationId: querylogDisable summary: 'Disable filtering' responses: 200: description: OK # -------------------------------------------------- # General statistics methods # -------------------------------------------------- /stats_top: get: tags: - stats operationId: statusTop summary: 'Get DNS server top client, domain and blocked statistics' responses: 200: description: OK schema: $ref: "#/definitions/StatsTop" /stats: get: tags: - stats operationId: stats summary: 'Get DNS server statistics' responses: 200: description: 'Returns general statistics for the last 24 hours' schema: $ref: "#/definitions/Stats" /stats_history: get: tags: - stats operationId: stats_history summary: 'Get historical DNS server statistics for the last 24 hours' parameters: - name: start_time in: query type: string description: 'Start time in ISO8601 (example: `2018-05-04T17:55:33+00:00`)' required: true - name: end_time in: query type: string description: 'End time in ISO8601 (example: `2018-05-04T17:55:33+00:00`)' required: true - name: time_unit in: query type: string description: 'Time unit (`minutes` or `hours`)' required: true enum: - minutes - hours responses: 501: description: 'Requested time window is outside of supported range. It will be supported later, but not now.' 200: description: 'Returns historical stats for the specified time interval.' schema: $ref: '#/definitions/StatsHistory' /stats_reset: post: tags: - stats operationId: statsReset summary: "Reset all statistics to zeroes" responses: 200: description: OK # -------------------------------------------------- # DHCP server methods # -------------------------------------------------- /dhcp/status: get: tags: - dhcp operationId: dhcpStatus summary: "Gets the current DHCP settings and status" responses: 200: description: OK schema: $ref: "#/definitions/DhcpStatus" /dhcp/set_config: post: tags: - dhcp operationId: dhcpSetConfig summary: "Updates the current DHCP server configuration" consumes: - application/json parameters: - in: "body" name: "body" description: "DHCP configuration JSON" required: true schema: $ref: "#/definitions/DhcpConfig" responses: 200: description: OK /dhcp/find_active_dhcp: post: tags: - dhcp operationId: checkActiveDhcp summary: "Searches for an active DHCP server on the network" responses: 200: description: OK schema: $ref: "#/definitions/DhcpSearchResult" # -------------------------------------------------- # Filtering status methods # -------------------------------------------------- /filtering/status: get: tags: - filtering operationId: filteringStatus summary: 'Get status of rules-based filter' responses: 200: description: OK schema: $ref: "#/definitions/FilteringStatus" /filtering/enable: post: tags: - filtering operationId: filteringEnable summary: 'Enable filtering' responses: 200: description: OK /filtering/disable: post: tags: - filtering operationId: filteringDisable summary: 'Disable filtering' responses: 200: description: OK /filtering/add_url: put: tags: - filtering operationId: filteringAddURL summary: 'Add filter URL' consumes: - text/plain parameters: - in: body name: url description: 'URL containing filtering rules' required: true schema: type: string example: 'url=https://filters.adtidy.org/windows/filters/15.txt' responses: 200: description: OK /filtering/remove_url: delete: tags: - filtering operationId: filteringRemoveURL summary: 'Remove filter URL' consumes: - text/plain parameters: - in: body name: url description: 'Previously added URL containing filtering rules' required: true schema: type: string example: 'url=https://filters.adtidy.org/windows/filters/15.txt' responses: 200: description: OK /filtering/enable_url: post: tags: - filtering operationId: filteringEnableURL summary: 'Enable filter URL' consumes: - text/plain parameters: - in: body name: url description: 'Previously added URL containing filtering rules' required: true schema: type: string example: 'url=https://filters.adtidy.org/windows/filters/15.txt' responses: 200: description: OK /filtering/disable_url: post: tags: - filtering operationId: filteringDisableURL summary: 'Disable filter URL' consumes: - text/plain parameters: - in: body name: url description: 'Previously added URL containing filtering rules' required: true schema: type: string example: 'url=https://filters.adtidy.org/windows/filters/15.txt' responses: 200: description: OK /filtering/refresh: post: tags: - filtering operationId: filteringRefresh summary: | Reload filtering rules from URLs This might be needed if new URL was just added and you dont want to wait for automatic refresh to kick in. This API request is ratelimited, so you can call it freely as often as you like, it wont create unneccessary burden on servers that host the URL. This should work as intended, a `force` parameter is offered as last-resort attempt to make filter lists fresh. If you ever find yourself using `force` to make something work that otherwise wont, this is a bug and report it accordingly. parameters: - name: force in: query type: boolean description: 'If any value is set, ignore cache and force re-download of all filters' responses: 200: description: OK with how many filters were actually updated /filtering/set_rules: put: tags: - filtering operationId: filteringSetRules summary: 'Set user-defined filter rules' consumes: - text/plain parameters: - in: body name: rules description: 'All filtering rules, one line per rule' schema: # TODO: move to definitions type: string example: '@@||yandex.ru^|' responses: 200: description: OK # -------------------------------------------------- # Safebrowsing methods # -------------------------------------------------- /safebrowsing/enable: post: tags: - safebrowsing operationId: safebrowsingEnable summary: 'Enable safebrowsing' responses: 200: description: OK /safebrowsing/disable: post: tags: - safebrowsing operationId: safebrowsingDisable summary: 'Disable safebrowsing' responses: 200: description: OK /safebrowsing/status: get: tags: - safebrowsing operationId: safebrowsingStatus summary: 'Get safebrowsing status' responses: 200: description: OK examples: application/json: enabled: false # -------------------------------------------------- # Parental control methods # -------------------------------------------------- /parental/enable: post: tags: - parental operationId: parentalEnable summary: 'Enable parental filtering' consumes: - text/plain parameters: - in: body name: sensitivity description: | Age sensitivity for parental filtering, EARLY_CHILDHOOD is 3 YOUNG is 10 TEEN is 13 MATURE is 17 required: true schema: type: string enum: - EARLY_CHILDHOOD - YOUNG - TEEN - MATURE example: 'sensitivity=TEEN' responses: 200: description: OK /parental/disable: post: tags: - parental operationId: parentalDisable summary: 'Disable parental filtering' responses: 200: description: OK /parental/status: get: tags: - parental operationId: parentalStatus summary: 'Get parental filtering status' responses: 200: description: OK examples: application/json: enabled: true sensitivity: 13 # -------------------------------------------------- # Safe search methods # -------------------------------------------------- /safesearch/enable: post: tags: - safesearch operationId: safesearchEnable summary: 'Enable safesearch' responses: 200: description: OK /safesearch/disable: post: tags: - safesearch operationId: safesearchDisable summary: 'Disable safesearch' responses: 200: description: OK /safesearch/status: get: tags: - safesearch operationId: safesearchStatus summary: 'Get safesearch status' responses: 200: description: OK examples: application/json: enabled: false # -------------------------------------------------- # I18N methods # -------------------------------------------------- /i18n/change_language: post: tags: - i18n operationId: changeLanguage summary: "Change current language. Argument must be an ISO 639-1 two-letter code" consumes: - text/plain parameters: - in: body name: language description: "New language. It must be known to the server and must be an ISO 639-1 two-letter code" schema: # TODO: use JSON? type: string example: en responses: 200: description: OK /i18n/current_language: get: tags: - i18n operationId: currentLanguage summary: "Get currently set language. Result is ISO 639-1 two-letter code. Empty result means default language." responses: 200: description: OK examples: text/plain: en definitions: ServerStatus: type: "object" description: "AdGuard Home server status and configuration" required: - "dns_address" - "dns_port" - "protection_enabled" - "querylog_enabled" - "running" - "bootstrap_dns" - "upstream_dns" - "version" - "language" properties: dns_address: type: "string" example: "127.0.0.1" dns_port: type: "integer" format: "int32" example: 53 minimum: 1 maximum: 65535 protection_enabled: type: "boolean" querylog_enabled: type: "boolean" running: type: "boolean" bootstrap_dns: type: "string" example: "8.8.8.8:53" upstream_dns: type: "array" items: type: "string" example: - "tls://1.1.1.1" - "tls://1.0.0.1" version: type: "string" example: "0.1" language: type: "string" example: "en" Filter: type: "object" description: "Filter subscription info" required: - "enabled" - "id" - "lastUpdated" - "name" - "rulesCount" - "url" properties: enabled: type: "boolean" id: type: "integer" example: 1234 lastUpdated: type: "string" format: "date-time" example: "2018-10-30T12:18:57.223101822+03:00" name: type: "string" example: "AdGuard Simplified Domain Names filter" rulesCount: type: "integer" example: 5912 url: type: "string" example: "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt" FilteringStatus: type: "object" description: "Filtering settings" required: - "enabled" - "filters" - "user_rules" properties: enabled: type: "boolean" filters: type: "array" items: $ref: "#/definitions/Filter" user_rules: type: "array" items: type: "string" example: - '||example.org^' - '||example.com^' VersionInfo: type: "object" description: "Information about the latest available version of AdGuard Home" required: - "version" - "announcement" - "announcement_url" - "download_darwin_amd64" - "download_linux_amd64" - "download_linux_386" - "download_linux_arm" - "selfupdate_min_version" properties: version: type: "string" example: "v0.9" announcement: type: "string" example: "AdGuard Home v0.9 is now available!" announcement_url: type: "string" example: "https://github.com/AdguardTeam/AdGuardHome/releases/tag/v0.9" download_darwin_amd64: type: "string" example: "https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.9/AdGuardHome_v0.9_MacOS.zip" download_linux_amd64: type: "string" example: "https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.9/AdGuardHome_v0.9_linux_amd64.tar.gz" download_linux_386: type: "string" example: "https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.9/AdGuardHome_v0.9_linux_386.tar.gz" download_linux_arm: type: "string" example: "https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.9/AdGuardHome_v0.9_linux_arm.tar.gz" selfupdate_min_version: type: "string" example: "v0.0" Stats: type: "object" description: "General server stats for the last 24 hours" required: - "dns_queries" - "blocked_filtering" - "replaced_safebrowsing" - "replaced_parental" - "replaced_safesearch" - "avg_processing_time" properties: dns_queries: type: "integer" description: "Total number of DNS queries" example: 123 blocked_filtering: type: "integer" description: "Number of requests blocked by filtering rules" example: 50 replaced_safebrowsing: type: "integer" description: "Number of requests blocked by the safebrowsing module" example: 5 replaced_parental: type: "integer" description: "Number of blocked adult websites" example: 15 avg_processing_time: type: "number" format: "float" description: "Average time in milliseconds on processing a DNS" example: 0.34 StatsTop: type: "object" description: "Server stats top charts" required: - "top_queried_domains" - "top_clients" - "top_blocked_domains" properties: top_queried_domains: type: "array" items: type: "object" example: example.org: 12312 example.com: 321 example.net: 5555 top_clients: type: "array" items: type: "object" example: 127.0.0.1: 12312 192.168.0.1: 13211 192.168.0.3: 13211 top_blocked_domains: type: "array" items: type: "object" example: example.org: 12312 example.com: 321 example.net: 5555 StatsHistory: type: "object" description: "Historical stats of the DNS server. Example below is for 5 minutes. Values are from oldest to newest." required: - "dns_queries" - "blocked_filtering" - "replaced_safebrowsing" - "replaced_parental" - "replaced_safesearch" - "avg_processing_time" properties: dns_queries: type: "array" items: type: "integer" example: - 1201 - 1501 - 1251 - 1231 - 120 blocked_filtering: type: "array" items: type: "integer" example: - 421 - 124 - 5 - 12 - 43 replaced_safebrowsing: type: "array" items: type: "integer" example: - 1 - 0 - 5 - 0 - 0 replaced_parental: type: "array" items: type: "integer" example: - 120 - 10 - 5 - 12 - 1 replaced_safesearch: type: "array" items: type: "integer" example: - 1 - 0 - 0 - 0 - 5 avg_processing_time: type: "array" items: type: "number" format: "float" example: - 1.25 - 5.12 - 4.12 - 123.12 - 0.12 DhcpConfig: type: "object" description: "Built-in DHCP server configuration" required: - "enabled" - "gateway_ip" - "subnet_mask" - "range_start" - "range_end" - "lease_duration" properties: enabled: type: "boolean" gateway_ip: type: "string" example: "192.168.1.1" subnet_mask: type: "string" example: "255.255.255.0" range_start: type: "string" example: "192.168.1.2" range_end: type: "string" example: "192.168.10.50" lease_duration: type: "string" example: "12h" DhcpLease: type: "object" description: "DHCP lease information" required: - "mac" - "ip" - "hostname" - "expires" properties: mac: type: "string" example: "001109b3b3b8" ip: type: "string" example: "192.168.1.22" hostname: type: "string" example: "dell" expires: type: "string" format: "date-time" example: "2017-07-21T17:32:28Z" DhcpStatus: type: "object" description: "Built-in DHCP server configuration and status" required: - "config" - "leases" properties: config: $ref: "#/definitions/DhcpConfig" leases: type: "array" items: $ref: "#/definitions/DhcpLease" DhcpSearchResult: type: "object" description: "Information about a DHCP server discovered in the current network" required: - "found" properties: found: type: "boolean" gateway_ip: type: "string" example: "192.168.1.1" DnsAnswer: type: "object" description: "DNS answer section" properties: ttl: type: "integer" example: 55 type: type: "string" example: "A" value: type: "string" example: "217.69.139.201" DnsQuestion: type: "object" description: "DNS question section" properties: class: type: "string" example: "IN" host: type: "string" example: "example.org" type: type: "string" example: "A" QueryLogItem: type: "object" description: "Query log item" properties: answer: type: "array" items: $ref: "#/definitions/DnsAnswer" client: type: "string" example: "192.168.0.1" elapsedMs: type: "string" example: "54.023928" question: $ref: "#/definitions/DnsQuestion" filterId: type: "integer" example: 123123 description: "In case if there's a rule applied to this DNS request, this is ID of the filter that rule belongs to." rule: type: "string" example: "||example.org^" description: "Filtering rule applied to the request (if any)" reason: type: "string" description: "DNS filter status" enum: - "NotFilteredNotFound" - "NotFilteredWhiteList" - "NotFilteredError" - "FilteredBlackList" - "FilteredSafeBrowsing" - "FilteredParental" - "FilteredInvalid" - "FilteredSafeSearch" status: type: "string" description: "DNS response status" example: "NOERROR" time: type: "string" description: "DNS request processing start time" example: "2018-11-26T00:02:41+03:00" QueryLog: type: "array" description: "Query log" items: $ref: "#/definitions/QueryLogItem"