Skip to content

Pi-hole API

The Pi-hole API is organized around REST. Our API has predictable resource-oriented URLs, accepts and returns reliable UTF-8 JavaScript Object Notation (JSON)-encoded data for all API responses, and uses standard HTTP response codes and verbs.

Most (but not all) endpoints require authentication. API endpoints requiring authentication will fail with code 401 Unauthorized if no key is supplied. See API Reference: Authentication for details.

Accessing the API documentation

The entire API is documented at http://pi.hole/api/docs and self-hosted by your Pi-hole to match 100% the API versions your local Pi-hole has. Using this locally served API documentation is preferred. In case you don't have Pi-hole installed yet, you can also check out the documentation for all branches online, e.g., Pi-hole API documentation (branch development-v6). Similarly, you can check out the documentation for a specific other branches by replacing development-v6 with the corresponding branch name.

API endpoints

An overview of all available endpoints is available at the API documentation page. The endpoints are grouped by their functionality.

JSON response

The form of replies to successful requests strongly depends on the selected endpoint, e.g.,

Example reply: Success

Resource: GET /api/dns/blocking

Response code: HTTP/1.1 200 OK

{
  "blocking": true
}

Reply type

Object or Array

Fields

Depending on the particular endpoint

In contrast, errors have a uniform, predictable style to ease their programmatic treatment:

Example reply: Error (unauthorized access)

Resource: GET /api/domains

Response code: HTTP/1.1 401 Unauthorized

{
    "error": {
        "key": "unauthorized",
        "message": "Unauthorized",
        "hint": null
    }
}

Reply type

Object

Fields

Key describing the error ("key": string)

This string may be used for internal categorization of error types

Examples for key are:

  • bad_request

    Possible reason: Payload is invalid for this endpoint

  • database_error

    Possible reason: Failed to read/write to the database

Human-readable description of the error ("message": string)

This string may be shown to the user for troubleshooting

Examples for messages are:

  • Could not read domains from database table

    Possible reason: Database is not readable

  • No request body data

    Possible reason: Payload is empty

  • Invalid request body data

    Possible reason: Payload is not valid JSON

  • No "domain" string in body data

    Possible reason: The required field domain is missing in the payload

Additional data ("hint": [object|string|null])

The field hint may contain a JSON object or string. Its content depends on the error itself and may contain further details such as the interpreted user data. If no additional hint is available for this endpoint, null is returned.

Examples for a failed request with hint being set is (domain is already on this list):

{
    "error":  {
        "key": "database_error",
        "message": "Could not add to gravity database",
        "hint": {
            "argument": "abc.com",
            "enabled": true,
            "sql_msg": "UNIQUE constraint failed: domainlist.domain, domainlist.type"
        }
    }
}

HTTP methods used by this API

Each HTTP request consists of a method that indicates the action to be performed on the identified resource. The relevant standards is RFC 2616. Though, RFC 2616 has been very clear in differentiating between the methods, complex wordings are a source of confusion for many users.

Pi-hole's API uses the methods like this:

Method Description
GET Read from resource
POST Create a resource
PATCH Update existing resource
PUT Create or Replace a resource
DELETE Delete existing resource
Summarized details from RFC 2616, Scn. 9 (GET/POST/PUT/DELETE) and RFC 2068, Scn. 19.6.1.1 (PATCH)

GET

The GET method means retrieve whatever information (in the form of an entity) that is identified by the URI.

As GET requests do not change the state of the resource, these are said to be safe methods. Additionally, GET requests are idempotent, which means that making multiple identical requests must produce the same result every time until another method (POST or PUT) has changed the state of the resource on the server.

For any given HTTP GET, if the resource is found on the server, then the API returns HTTP response code 200 (OK) – along with the response body.

In case a resource is NOT found on server, then the API returns HTTP response code 404 (Not found). Similarly, if it is determined that GET request itself is not correctly formed then API will return HTTP response code 400 (Bad request).

POST

Use POST APIs to create new subordinate records, e.g., a file is subordinate to a directory containing it or a row is subordinate to a database table. WPOST methods are used to create a new resource into the collection of resources.

If a resource has been created on the origin server, the response will be 201 (Created). Not all action performed using the POST method will result in a resource that can be identified by a URI. In such a case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

Note that POST is neither safe nor idempotent, and invoking two identical POST requests typically results in an error.

PUT

Use PUT primarily to update existing records (if the resource does not exist, the API will typically create a new record for it). If a new record has been added at the given URI, or an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes are sent to indicate successful completion of the request.

PATCH

The PATCH method is similar to PUT except that the entity contains a list of differences between the original version of the resource identified by the Request-URI and the desired content of the resource after the `PATCH`` action has been applied. The list of differences is in a format defined by the media type of the entity (e.g., "application/diff") and MUST include sufficient information to allow the server to recreate the changes necessary to convert the original version of the resource to the desired version.

DELETE

As the name applies, DELETE APIs are used to delete records (identified by the Request-URI).

A successful response will be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

DELETE operations are idempotent. If you DELETE a resource, it’s removed from the collection of resources. Repeatedly calling DELETE on that resource will not change the outcome – however, calling DELETE on a resource a second time may return a 404 (NOT FOUND) since it was already removed.

Example

Let’s list down few URIs and their purpose to get better understanding when to use which method:

Method + URI Interpretation
GET /api/groups Get all groups
POST /api/groups Create a new group
GET /api/groups/abc Get the group abc
PUT /api/groups/abc Update the group abc
DELETE /api/groups/abc Delete group abc

Error handling

Pi-hole uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, missing authentication, etc.). Codes in the 5xx range indicate an error with Pi-hole's API (these are rare).

Some 4xx errors that could be handled programmatically include an error code that briefly explains the error reported:

Code Description Interpretation
200 OK Everything worked as expected
201 Content Created Added a new item
204 No Content Removed an item
400 Bad Request The request was unacceptable, often due to a missing required parameter
401 Unauthorized No session identity provided for endpoint requiring authorization
402 Request Failed The parameters were valid but the request failed
403 Forbidden The API key doesn't have permissions to perform the request
404 Not Found The requested resource doesn't exist
429 Too Many Requests Too many requests hit the API too quickly
500, 502, 503, 504 Server Errors Something went wrong on Pi-hole's end (These are rare)

We recommend writing code that gracefully handles all possible API exceptions. The Pi-hole API is designed to support this by standardized error messages and human-readable hints for errors.