# REST API overview

<span class="">All administration and configuration of SafeDNS Shield is performed through the REST API. The API listens on port 8080 of the same IP address that handles DNS queries. By default, access is restricted to a set of whitelisted IP addresses specified during deployment.</span>

#### <span class="">Initial Configuration Example</span>

<span class="">The following example demonstrates the initial configuration workflow. Send the following request:</span>

<div class="pointer-container" id="bkmrk-%C2%A0"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: POST
- URL: `<domain>/init/`
- Data:

```
{
    "profiles": [
        {
            "profile": {
                "id": 1,
                "page_id": 1
            },
            "cat_ids": [3, 4, 12],
            "app_ids": [1, 12, 93]
        }
    ],
    "blockpages": [
        {
            "id": 1,
            "type": 0
        },
        {
            "id": 2,
            "type": 1
        }
    ],
    "bw_lists": [
       {
            "profile_id": 1,
            "type": "deny",
            "domains": [
                "example1.com",
                "example2.com",
                "example3.com"
            ]
        }
    ],
    "nets": [
        {
            "ip": "100.100.100.100",
            "profile_id": 1,
            "prefix_len": 32
        },
        {
            "ip": "100.110.110.0",
            "profile_id": 1,
            "prefix_len": 24
        },
        {
            "ip": "100.120.0.0",
            "profile_id": 1,
            "prefix_len": 16
        }
    ],
    "nets6": [],
    "napts": []
}
```

<span class="">The initialization query defines the full configuration applied to SafeDNS Shield. The following settings are processed in sequence:</span>

1. **<span class="">Filtering profile and block page</span>**<span class=""> – A filtering profile (ID=1) and a block page (ID=1) are created.</span>
2. **<span class="">Blocked categories</span>**<span class=""> – Three DNS categories are blocked for the profile: malware, phishing, and botnets.</span>
3. **<span class="">Blocked applications</span>**<span class=""> – Three AppBlocker categories are blocked: Slack, AnyDesk, and Netflix.</span>
4. **<span class="">Block pages</span>**<span class=""> – Two block pages of different types are created:</span>
    
    
    - <span class="">Type 0 – displays the blocked domain name.</span>
    - <span class="">Type 1 – does not display the blocked domain name.</span>
5. **<span class="">Blacklist</span>**<span class=""> – Three domains are added to the blacklist for filtering profile 1.</span>
6. **<span class="">IP assignment</span>**<span class=""> – The profile is assigned one specific IP address and two subnets (/16 and /24). DNS requests from these sources are filtered according to the profile’s policy.</span>
7. **<span class="">IPv6 and NAT‑port identification</span>**<span class=""> – The </span>`nets6`<span class=""> (IPv6) and </span>`napts`<span class=""> (NAT port‑based identification) sections are included but left empty. These fields must be present in the request even if not used, to trigger the creation of the initial configuration.</span>

<span class="">Once the request is sent and a successful response (HTTP status </span>`204`<span class="">) is received, the initial configuration is complete. All subsequent DNS traffic processed by the server is handled according to the specified rules.</span>

##### Modifying Filtering Categories

<span class="">To modify the filtering categories for an existing profile, you must update the entire list of categories assigned to that profile. Adding new categories requires sending the full set (both current and new categories) in a single request.</span>

<span class="">For example, the initial configuration created profile </span>`id=1`<span class=""> with three blocked categories: malware, phishing, and botnets. To add Cryptojacking, DGA, and Ransomware, the request must include all six categories:</span>

<div class="pointer-container" id="bkmrk-%C2%A0-0"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: PATCH
- URL: `<domain>/profiles/<strong>1</strong>/`
- Data:

```
{
  "cat_ids": [3, 4, 12, 66, 70, 71],
  "app_ids": [1, 12, 93],
  "profile": {
    "page_id": 1
  }
}
```

In this request, the profile ID is specified directly in the URL. The request body contains the updated list of categories (original three and three new) while the AppBlocker categories and block page remain unchanged.

##### Adding a Domain to the Allowlist

<span class="">To exempt a specific domain from category-based blocking, add it to the allowlist of the relevant filtering profile. For profile </span>`id=1`<span class="">, send the following request:</span>

<div class="pointer-container" id="bkmrk-%C2%A0-1"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: POST
- URL: `<domain>/profile/<strong>1</strong>/bw_list`
- Data:

```
{
  "type": "allow",
  "domain": "example4.com"
}
```

<span class="">This adds the domain to the allowlist, giving it priority over category-based blocking.</span>

##### <span class="">Adding Domains to the Denylist</span>

<span class="">To block specific domains that are not covered by the configured categories, add them directly to the denylist for the filtering profile. The following request adds domains in a batch operation for profile </span>`id=1`<span class="">:</span>

<div class="pointer-container" id="bkmrk-%C2%A0-2"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: POST
- URL: `<domain>/profile/<strong>1</strong>/bw_list/batch`
- Data:

```
{
  "type": "deny",
  "domains": ["example5.com", "example6.com", "example7.com", "example8.com", "example9.com"]
}
```

##### <span class="">Adding a Network or IP Address for Filtering</span>

<span class="">To assign a new IP address or subnet to a filtering profile, send the following request. The example adds a single IP address by specifying a </span>`/32`<span class=""> network prefix for profile </span>`id=1`<span class="">:</span>

<div class="pointer-container" id="bkmrk-%C2%A0-3"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: POST
- URL: `<domain>/net/`
- Data:

```
{
    "ip": "100.100.100.101",
    "profile_id": 1,
    "prefix_len": 32
}
```

<span class="">To add an entire subnet, adjust the prefix length accordingly. For instance, a </span>`/24`<span class=""> subnet would be specified as:</span>

```
{
    "ip": "100.100.101.0",
    "profile_id": 1,
    "prefix_len": 24
}
```

##### <span class="">Removing an IP Address from Filtering</span>

<span class="">To remove a previously assigned IP address or subnet from a filtering profile, send the following request:</span>

- Type: DELETE
- URL: `<domain>/net/<strong>1684300901</strong>`
- Data: None

<span class="">This request has no body. The IP address must be provided in decimal format in the URL. Use the exact address originally submitted, without the mask - for example, </span>`100.100.100.101`<span class=""> or </span>`100.100.101.0`<span class=""> from the earlier examples. You can convert an IP address to decimal format using a tool like [this one](https://www.browserling.com/tools/ip-to-dec).</span>

##### Modifying the Filtering Profile for a Specific IP

<span class="">To change the filtering profile assigned to an existing IP address or subnet, send the following request. The IP address must be provided in decimal format in the URL. This example reassigns the address </span>`100.100.101.0`<span class=""> (originally a </span>`/24`<span class=""> subnet) from profile </span>`id=1`<span class=""> to profile </span>`id=2`<span class="">:</span>

<div class="pointer-container" id="bkmrk-%C2%A0-4"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: PATCH
- URL: `<domain>/net/<strong>1684301056</strong>`
- Data:

```
{
    "ip": "100.100.101.0",
    "profile_id": 2,
    "prefix_len": 24
}
```

<span class="">To change the network prefix (for example, from </span>`/24`<span class=""> to </span>`/16`<span class="">), you must delete the existing record and add a new one with the correct network address. In this case, you would delete </span>`100.100.101.0`<span class=""> and add </span>`100.100.0.0`<span class=""> with the </span>`/16`<span class=""> prefix.</span>

##### Creating a New Filtering Profile

Before an IP can be reassigned to a different profile, that profile must exist. The following request creates a new filtering profile:

<div class="pointer-container" id="bkmrk-%C2%A0-5"><div class="pointer anim is-page-editable"><svg class="svg-icon" data-icon="link" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg><div class="input-group inline block"> <button class="button outline icon" data-clipboard-target="#pointer-url" title="Copy Link" type="button"><svg class="svg-icon" data-icon="copy" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></button></div><svg class="svg-icon" data-icon="edit" role="presentation" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"></svg></div></div>- Type: POST
- URL: `<domain>/profiles/`
- Data:

```
<br></br><br></br>```
{
    "profile": {
        "id": 2,
        "page_id": 1
    },
    "cat_ids": [3, 4, 12, 66, 70, 71, 13],
    "app_ids": [1, 12, 93]
}
```
```

<span class="">This creates profile </span>`id=2`<span class="">, configured with the same block page type and the same categories and AppBlocker settings as profile </span>`id=1`<span class="">, with the addition of the "Adult Related" category.</span>